<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Karam Kabbara</title>
    <description>The latest articles on DEV Community by Karam Kabbara (@karam).</description>
    <link>https://dev.to/karam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F203500%2F1ef24a0d-95aa-4600-a796-d4d140372422.jpg</url>
      <title>DEV Community: Karam Kabbara</title>
      <link>https://dev.to/karam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karam"/>
    <language>en</language>
    <item>
      <title>Easily test your Vuex store using Vue Test Utils.</title>
      <dc:creator>Karam Kabbara</dc:creator>
      <pubDate>Sun, 02 Aug 2020 15:34:48 +0000</pubDate>
      <link>https://dev.to/karam/easily-test-your-vuex-store-using-vue-test-utils-3172</link>
      <guid>https://dev.to/karam/easily-test-your-vuex-store-using-vue-test-utils-3172</guid>
      <description>&lt;p&gt;If you like &lt;a href="https://vuejs.org/"&gt;Vue.js&lt;/a&gt;, then you probably already know what &lt;a href="https://vuex.vuejs.org/%5D"&gt;Vuex&lt;/a&gt; is. It's a state management pattern &amp;amp; library for Vue.js applications that is inspired by a Flux/Redux-like architecture.&lt;/p&gt;

&lt;p&gt;The library is developed and maintained by the Vue.js development team, which means it is the official recommended state management library for the framework. No more state management framework arguments!&lt;/p&gt;

&lt;p&gt;This post is going to encapsulate a technique I've come across that allows you to easily write tests around your Vuex store that results in far less brittle tests, than unit testing the individual moving parts individually.&lt;/p&gt;

&lt;p&gt;Vuex is made up of numerous core concepts. Actions, mutations and getters are the main moving parts. Because they are all written as plain JavaScript functions, they can all therefore be unit tested in isolation quite easily.&lt;/p&gt;

&lt;p&gt;The issue with this approach though is that it leads to brittle tests and sometimes, false-positives. For example, to unit test an action, we might test that it ends up commiting a specific mutation, with certain expected parameters. We could quite easily use &lt;a href="https://jestjs.io/"&gt;Jest&lt;/a&gt; to do this.&lt;/p&gt;

&lt;p&gt;The problem however is, what would happen if we changed the name of one of our Vuex action functions? Firstly, our test would fail to run because it no longer imports/references a function that exists. Since our test would import the actions function directly, we would simply rename the function call to pass the test.&lt;/p&gt;

&lt;p&gt;However, within our actual Vue component code, we will be doing &lt;code&gt;this.$store.dispatch('oldActionName')&lt;/code&gt; in order to dispatch our action, not directly importing the action function. Therefore, if we don't have adequate end to end testing within our application, we could quite easily find ourselves in the scenario where we have passing unit tests but an application that doesn't work because we're still dispatching the old action!&lt;/p&gt;

&lt;p&gt;Fortunately though, the amazing Vue development team who are also behind Vue's official unit testing library (which uses Jest too by the way) - &lt;a href="https://vue-test-utils.vuejs.org/"&gt;Vue Test Utils&lt;/a&gt; - have given us an easy solution for this problem. The solution, believe it or not, is to just facilitate the testing of our Vuex store as a whole, rather than the individual cogs.&lt;/p&gt;

&lt;p&gt;Below is a walkthrough with example pseudo-ish code modelled on how I've managed to test my store without running in to any of these problems.&lt;/p&gt;

&lt;p&gt;In this case, we are going to test our store end to end, actions, mutations, getters, you name it, all within a single test. I've seen some argue that this is an integration test, however since all external collaborators should still be mocked, I'd argue it's just a slightly larger unit test.&lt;/p&gt;

&lt;p&gt;The scenario is an Instagram-like post feed. I have a &lt;code&gt;loadPosts&lt;/code&gt; action within the posts slice of my Vuex store, which uses &lt;a href="https://github.com/axios/axios"&gt;axios&lt;/a&gt; to make an asynchronous remote call to an API to retrieve these posts and then place them within the application's global Vuex state.&lt;/p&gt;

&lt;p&gt;We begin by defining our Vuex store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vuex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./modules/posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;posts&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next we define what our posts Vuex state slice/module looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mutations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;SET_POSTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;loadPosts&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;commit&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;axios&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/posts/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SET_POSTS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;namespaced&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;getters&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we're storing a list of posts as part of our state. We have our &lt;code&gt;loadPosts&lt;/code&gt; action that triggers the axios call. We have our &lt;code&gt;SET_POSTS&lt;/code&gt; mutation that changes our value of &lt;code&gt;posts&lt;/code&gt; within our global state and finally we have a getter called &lt;code&gt;getPosts&lt;/code&gt; that we can use to retrieve the value of &lt;code&gt;posts&lt;/code&gt; from our state.&lt;/p&gt;

&lt;p&gt;Now in order to test our state, it's simple. We want to dispatch the &lt;code&gt;loadPosts&lt;/code&gt; action to our store and then assert that the expected value, is obviously stored within our store. Simple, right? In order to do this, we have to touch all the moving parts of our Vuex store within the test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vuex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createLocalVue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vue/test-utils&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createStoreConfig&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./__mocks__/storeConfig&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mockPosts&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./__mocks__/posts.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;createLocalVue&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storeConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStoreConfig&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;storeConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../modules/posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createStoreConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we use the &lt;code&gt;createLocalVue&lt;/code&gt; class provided to us by Vue Test Utils to create a Vue class for us to add our components, plugins (Vuex in this case) to, to use as part of our test without polluting the global Vue class. We put this within our &lt;code&gt;beforeEach&lt;/code&gt; which ensures that every store test, not only uses a separate Vue instance but also starts off fresh with a blank store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vuex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createLocalVue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vue/test-utils&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createStoreConfig&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./__mocks__/storeConfig&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mockPosts&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./__mocks__/posts.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mockPosts&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;createLocalVue&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storeConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStoreConfig&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;storeConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Post Store Tests&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loads posts and updates them in state&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;posts/loadPosts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;posts/getPosts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockPosts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In order to write our test, we need to mock our axios API call. We can use Jest to do this. In this case, I've opted to store a similar JSON representation of the data that would come back from the real API in a JSON file, however in theory you can use whatever you want, as long as it ends up being stored in state. The reason why we want to mock our axios calls is to prevent our unit tests taking a long time to run and to ensure we have no external dependencies which could cause obvious problems (e.g. if the API ever went down, our tests would fail even though our code in theory works fine).&lt;/p&gt;

&lt;p&gt;The test itself is simple. We use the store object we create before the running of each test to dispatch the action we want to test. If this action works correctly, then it should trigger the mutation too, under the hood. We then use our getter on the store to assert that the data within the state has mutated as expected. Done and dusted!&lt;/p&gt;

&lt;p&gt;One of the great things about testing our Vuex store this way is that within our test, we are calling &lt;code&gt;store.dispatch("posts/loadPosts")&lt;/code&gt; the exact same way our real smart components are. We're no longer importing the &lt;code&gt;loadPosts&lt;/code&gt; function directly and testing it under different circumstances to how our actual application is using it. So, if our test breaks, then our application is most certainly also broken!&lt;/p&gt;

&lt;p&gt;If any part of the Vuex journey to mutate an element of state breaks, the test will know about it. The main downside to this approach versus the more granular approach, is that it will be harder to debug exactly what moving part went wrong.&lt;/p&gt;

&lt;p&gt;Hope this helps...&lt;br&gt;
and as always, thanks for reading!&lt;/p&gt;

&lt;p&gt;PS: If you enjoyed the post, don't forget that you can find more of my work directly on my blog at &lt;a href="http://karam.io"&gt;http://karam.io&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>testing</category>
    </item>
    <item>
      <title>Tips for learning a new code base.</title>
      <dc:creator>Karam Kabbara</dc:creator>
      <pubDate>Mon, 18 May 2020 21:55:54 +0000</pubDate>
      <link>https://dev.to/karam/tips-for-learning-a-new-code-base-403d</link>
      <guid>https://dev.to/karam/tips-for-learning-a-new-code-base-403d</guid>
      <description>&lt;p&gt;I don't usually talk much about my adventures within the professional world of software development on this blog, but I feel like an article about this topic is far too relevant to just about everyone, not to write about.&lt;/p&gt;

&lt;p&gt;As you can probably tell from the title, it's about familiarising yourselves with new code bases and unsurprisingly, this situation usually comes to those who have recently changed teams or jobs.&lt;/p&gt;

&lt;p&gt;I changed jobs roughly 6 months ago and my new role is within a consultancy, therefore as you can imagine, not only are you required to become familiar with codebases (and sometimes new technologies) relatively often as you swap between new clients, but you also have to be prepared in accomplishing to do so within a relatively quick amount of time becuase you're expected to a certain extent, to hit the ground running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning a new code base:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tip #1 - Know your boundaries:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You aren't going to learn everything overnight. Understand from your colleagues exactly what services, APIs &amp;amp; bananas you need to know about and concern yourself with. Find out which of those you will actually be working within and which of those you have only been told about only because you may need to communicate with them. Your aim should be to reduce the scope of what you need to learn as much as possible.&lt;/p&gt;

&lt;p&gt;Businesses tend to have tens of different solutions, but domain aligned teams or projects only tend to touch a sub-set of them. This can also help you mentally if you feel overwhelmed as those 90 solutions you were worried about needing to learn, have suddenly become only 10.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #2 - Understand the context &amp;amp; architecture:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before you start to worry about the micro-architecture of applications (which refers to the structure of the code bases), you first need to understand the context and purpose of these different services, including how and why they communicate with each other. Why do they exist in the first place? What value are they bringing to the table? Why are they the ones you need to work on within your particular team/role?&lt;/p&gt;

&lt;p&gt;I recommend the C4 Model as a fantastic way to draw a high level architectural diagram for this kind of thing. You can also use it to diagram the internals of an application once you get past this point. This will leave you with diagrams of both the macro and micro-architecture of what you need to learn about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #3 - Ask questions:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The only stupid question, is not asking any questions.&lt;/p&gt;

&lt;p&gt;If you can't think of any questions, ask about the coding conventions/standards. If there aren't any, then it's a good chance for you to make an instant impact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #4 - Read the documentation, tests are part of the documentation process:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some places will have long winded documentation for software (that is most likely out of date) whilst others won't. What all places however should have within a code base though is relatively decent test coverage, which is the best kind of documentation as it inevitably evolves and updates with the codebase... one would hope!&lt;/p&gt;

&lt;p&gt;Look at the different test files, focus on a small subset of them and work your way inwards. At this point you won't learn too many implementation details but you should be seeing references to functions or classes referred to in these tests, navigate in to them to gain a rough understanding of what methods also exist within the codebase in terms of the file structure. This gives you an idea of what use cases are fulfilled by the software, as they are what are under test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #5 - Read the code:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You now understand why all the different services exist, you understand how they all communicate and you understand roughly what classes or files exist inside a particular code base. Now it's time to understand the implementation details.&lt;/p&gt;

&lt;p&gt;As you did in tip #4, start with the tests. Work your way inwards, but this time pay attention to the specifics of what makes these tests pass, which is the implementation detail.&lt;/p&gt;

&lt;p&gt;This is great because rather than focusing on learning a huge codebase all at once, you focus on learning the implementation details of a method. Then that method becomes learning the implementation details of the other methods in the same class, until you've seen and read it all.&lt;/p&gt;

&lt;p&gt;Rinse and repeat this process. Tackle the codebase like you would a jigsaw, complete one corner, then the other and eventually it will all come together. Those of you who are more experienced, may also spot refactoring opportunities as a pair of fresh eyes, take a note of these.&lt;/p&gt;

&lt;p&gt;Divide and conquer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #6 - Look at past commits/pull requests:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Did a feature being implemented by your colleague mentioned during your daily scrum sound interesting? Look at how they implemented it, what do you think? Look where they placed certain bits of logic and their overall approach. If you are unsure about anything, ask.&lt;/p&gt;

&lt;p&gt;Were there any PR comments about the implementation from other colleagues which may contain hidden gems of things you should know about to do with the codebase? If not the codebase, then the conventions used within it?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #7 - Pair programming:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Obviously, working with a developer who is more familiar with a codebase or even potentially more experienced than you, will help you and significantly speed you up at the start of your new journey. However I believe there is another benefit than just purely technical and what you usually get in terms of benefits of pair programming.&lt;/p&gt;

&lt;p&gt;We can all read code and eventually understand it, but the code doesn't always tell the full story of a piece of software. Some of your colleagues may have been amongst the original authors of a codebase or regular contributors. Whilst you pair, they may provide extra insight in to decisions that were made months ago, relevant to the work you're currently implementing. These decisions could be the use of certain libraries or opting to use a certain design pattern for example.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #8 - Break the code:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As you're learning a codebase, you most likely have it pulled down on to your machine by now.&lt;/p&gt;

&lt;p&gt;Try to implement a feature on the backlog for next sprint, this way you don't have the pressure of a looming deadline to meet, or just try to change or refactor the existing code around and see what happens.&lt;/p&gt;

&lt;p&gt;Note that I'm not saying you should actively seek to do work... outside of work. You can come up with your own use case/user story if you wish instead of picking something up off the backlog for next sprint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #9 - Take notes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I use the notes app on my Macbook as it allows me to copy and paste code snippets to refer back to, however there's also nothing wrong with a good old fashioned notepad and pen. Chances are, if you've written something down, others will probably want it documented too. This brings us nicely to our final tip...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #10 - Reflect back on yourself:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What else did you struggle with during the onboarding/codebase learning process? Do something about it and make the next new developers onboarding experience better than yours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning new technologies:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tip #1 - Online courses:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider a Pluralsight subscription, a Udemy course or a simple search on YouTube.&lt;/p&gt;

&lt;p&gt;Dedicate a day or two towards learning the basics. Remember that you don't need to be an expert and that as a new developer, you ARE expected to learn on the job.&lt;/p&gt;

&lt;p&gt;Aim to know the basics and the rest will come with time and through applying what you already know from other technologies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #2 - Cheat sheets:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write your own cheat sheets for each technology that you can refer back to. I like to just create a bunch of private repositories on my GitHub and write the cheat sheets using markdown in the &lt;code&gt;README.md&lt;/code&gt; files.&lt;/p&gt;

&lt;p&gt;Different people will want different things out of their cheat sheets. We all think slightly differently and as a result may prefer different formats of things to refer back to when we are stuck.&lt;/p&gt;

&lt;p&gt;I end up writing cheat sheets that encapsulate a load of snippets of doing basic things. An example of this could be what a simple snippet of a functional React component looks like that deals with a simple use case such as with an onClick handler.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip #3 - Build something:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;...without using a tutorial in your own time. Do not fall in to tutorial purgatory and keep it simple.&lt;/p&gt;

&lt;p&gt;In conclusion, these are the tips I'd have given myself 6 months ago. Are there any tips you think I may have missed out? Let me (and all the other developers who will come across this post) know in the comments below.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;PS: If you enjoyed the post, don't forget that you can find more of my work directly on my blog at &lt;a href="http://karam.io"&gt;http://karam.io&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
