title: Vue unit tests failing because component method calls this.$route.query - TypeError: Cannot read property 'query' of undefined
body: <p>Long time user of the wisdom of StackOverflow on and off the job, but first time I'm posting a question. What a milestone!</p>
  
  <p>I'm writing unit tests for a large Vue application, and one of my components uses a method that references $route in order to determine if a query param is being passed in / pass in the param if it is being used. The method calling this.$route.query.article_id works great, however now that I am in testing, the tests don't recognize this.$route.query</p>
  
  <p>I've tried to mock the $route object when using shallowMount to mount my localVue, as described in the doc, but it doesn't work, and I continue to get the same error.</p>
  
  <p>Here is my component: </p>
  
  <pre><code>&lt;template&gt;
    &lt;b-container fluid&gt;
      &lt;div class="content-page-header"&gt;&lt;/div&gt;
      &lt;b-row&gt;
        &lt;b-col cols="3" class="outer-columns text-center" style="color:grey"&gt;
          &lt;font-awesome-icon
            :icon="['fas', 'newspaper']"
            class="fa-9x content-page-photo mb-3 circle-icon"
          /&gt;
          &lt;br /&gt;
          &lt;br /&gt;Get practical tips and helpful
          &lt;br /&gt;advice in clear articles written
          &lt;br /&gt;by our staff's experts.
        &lt;/b-col&gt;
        &lt;b-col cols="6" v-if="articlesExist"&gt;
          &lt;h1 class="header-text"&gt;
            &lt;b&gt;Articles&lt;/b&gt;
          &lt;/h1&gt;
          &lt;div v-if="!selectedArticle"&gt;
            &lt;div v-for="article in articles"&gt;
              &lt;article-card :article="article" @clicked="onClickRead" /&gt;
              &lt;br /&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          &lt;div v-else&gt;
            &lt;router-link to="articles" v-on:click.native="setSelectedArticle(null)"&gt;
              &lt;font-awesome-icon icon="chevron-circle-left" /&gt;&amp;nbsp
              &lt;b&gt;Back to All Articles&lt;/b&gt;
            &lt;/router-link&gt;
            &lt;article-header :article="selectedArticle" /&gt;
            &lt;br /&gt;
            &lt;span v-html="selectedArticle.text"&gt;&lt;/span&gt;
          &lt;/div&gt;
        &lt;/b-col&gt;
        &lt;b-col cols="6" v-else&gt;
          &lt;h1 class="header-text"&gt;
            &lt;b&gt;Articles&lt;/b&gt;
          &lt;/h1&gt;
          &lt;div class="text-center"&gt;Stay tuned for more Articles&lt;/div&gt;
        &lt;/b-col&gt;
        &lt;b-col class="outer-columns"&gt;
          &lt;b class="text-color" style="font-size:14pt"&gt;Saved Articles&lt;/b&gt;
          &lt;div v-for="article in userArticles"&gt;
            &lt;router-link
              :to="{path:'articles', query: {article_id: article.article.id}}"
              v-on:click.native="setSelectedArticle(article.article)"
            &gt;
              &lt;user-article :article="article.article" /&gt;
            &lt;/router-link&gt;
            &lt;br /&gt;
          &lt;/div&gt;
        &lt;/b-col&gt;
      &lt;/b-row&gt;
    &lt;/b-container&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  import ArticleCard from "./ArticleCard";
  import UserArticle from "./UserArticle";
  import ArticleHeader from "./ArticleHeader";
  import { library } from "@fortawesome/fontawesome-svg-core";
  import {
    faNewspaper,
    faChevronCircleLeft
  } from "@fortawesome/free-solid-svg-icons";
  import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
  
  library.add(faNewspaper, faChevronCircleLeft);
  
  export default {
    name: "Articles",
  
    props: [],
  
    components: {
      ArticleCard,
      ArticleHeader,
      UserArticle,
      library,
      FontAwesomeIcon,
      faNewspaper,
      faChevronCircleLeft
    },
  
    mixins: [],
  
    data() {
      return {
        selectedArticle: null
      };
    },
  
    computed: {
      articles() {
        return this.$store.getters.articles.filter(article =&gt; article.text);
      },
      articlesExist() {
        return Array.isArray(this.articles) &amp;&amp; this.articles.length;
      },
      userArticles() {
        return this.$store.getters.userArticles;
      },
      articleParam() {
        return parseInt(this.$route.query.article_id);
      }
    },
  
    methods: {
      setSelectedArticle(article) {
        this.selectedArticle = article;
      },
      onClickRead(article) {
        this.selectedArticle = article;
      }
    },
  
    mounted() {
      if (this.articleParam) {
        this.setSelectedArticle(
          this.articles.filter(article =&gt; article.id === this.articleParam)[0]
        );
      }
    }
  };
  &lt;/script&gt;
  
  &lt;style lang="stylus" scoped&gt;
  .text-color {
    color: #549DB0;
  }
  
  .header-text {
    color: white;
    margin-top: -50px;
    margin-bottom: 20px;
  }
  
  .outer-columns {
    background-color: #F2FBFD;
    padding-top: 20px;
  }
  
  .nav-back {
    color: #549DB0;
    background-color: #F0FBFD;
    padding: 5px;
  }
  &lt;/style&gt;
  </code></pre>
  
  <p>And here is my test:</p>
  
  <pre><code>import { shallowMount, createLocalVue } from '@vue/test-utils'
  import VueRouter from 'vue-router'
  import Articles from '../../../app/javascript/components/member-dashboard/Articles.vue'
  
  const localVue = createLocalVue()
  localVue.use(Vuex)
  localVue.use(VueRouter)
  localVue.use(BootstrapVue)
  
  describe('Articles', () =&gt; {
      let store
      let getters
      let state = {
          articles: [
              {
                  title: "Testing Vue Components"                
              },
              {
                  title: "This One shows",
                  text: "&lt;p&gt;You can see me!&lt;/p&gt;"
              },
              {
                  title: "Another One",
                  text: "&lt;p&gt;See me too!&lt;/p&gt;"
              }
          ],
          userArticles: [
              {article: {
                  title: "This One shows",
                  text: "&lt;p&gt;You can see me!&lt;/p&gt;"
              }},
              {article: {
                  title: "Another One",
                  text: "&lt;p&gt;See me too!&lt;/p&gt;"
              }}
          ]
      }
  
      beforeEach(() =&gt; {
          getters = {
              articles: () =&gt; {
                  return state.articles
              },
              userArticles: () =&gt; {
                  return state.userArticles
              }
          }
  
          store = new Vuex.Store({ getters })
      })
  
      it('only displays article with body text', () =&gt; {
          const wrapper = shallowMount(Articles, {
              store,
              localVue
          })
  
          expect(wrapper.vm.articles.length).to.deep.equal(2)
      })
  })
  </code></pre>
  
  <p>As I mentioned, in the shallow mount, I've tried doing this:</p>
  
  <pre><code> const wrapper = shallowMount(Articles, {
              store,
              localVue,
              mocks: {
                  $route: {
                      query: null
                  }
              }
          })
  </code></pre>
  
  <p>But I continue to get this error:</p>
  
  <pre><code>TypeError: Cannot read property 'query' of undefined
        at VueComponent.articleParam (webpack-internal:///1:107:35)
  </code></pre>
  
  <p>When I remove the line <code>return parseInt(this.$route.query.article_id);</code> from the articleParam method, my test passes.</p>
  
  <p>How do I get around this call to this.$route.query in the component? It's not necessary to my test, but is causing my test to fail when mounting the component.</p>