<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>webcodr</title>
    <link>https://webcodr.io/topics/testing/</link>
    <description>Recent content on webcodr</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 29 Aug 2020 22:26:07 +0200</lastBuildDate>
    <atom:link href="https://webcodr.io/topics/testing/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Kotest and JUnit with IntelliJ or: don’t frak up your toolchain upgrades</title>
      <link>https://webcodr.io/2020/08/kotest-and-junit-with-intellij-or-dont-frak-up-your-toolchain-upgrades/</link>
      <pubDate>Sat, 29 Aug 2020 22:26:07 +0200</pubDate>
      <guid>https://webcodr.io/2020/08/kotest-and-junit-with-intellij-or-dont-frak-up-your-toolchain-upgrades/</guid>
      <description>My team and I recently decided to use Kotlin for new features in our existing project. It was a great choice to implement a new authentication process and we’re now rewriting some older parts of the application from Java to Kotlin.
Actually I wanted to use Kotlin for a while now, but there were only minor tasks within the Java part of the project. That finally changed and we can focus to improve the Java backend drastically.
</description>
      <content:encoded><![CDATA[<p>My team and I recently decided to use Kotlin for new features in our existing project. It was a great choice to implement a new authentication process and we’re now rewriting some older parts of the application from Java to Kotlin.</p>
<p>Actually I wanted to use Kotlin for a while now, but there were only minor tasks within the Java part of the project. That finally changed and we can focus to improve the Java backend drastically.</p>
<p>Part of this process was a library update. We decided to upgrade JUnit from 4 to 5. A big pain in the ass. I don’t think, I would do it again. JUnit 5 was also part of a bigger problem, even if it was actually PEBKAC.</p>
<h2 id="kotest-and-mockk-features"><a href="#kotest-and-mockk-features" class="heading-anchor">Kotest and MockK features</a></h2>
<p>If you already know about Kotest or want to know more about the problem I had, just skip to the next headline. The Kotest introduction is a little bit longer.</p>
<p>As I dived more and more into Kotlin, I stumbled over Kotest. A really neat testing framework for Kotlin. There’s nothing wrong with JUnit, but Kotest gives you way more awesome ways to structure your tests.</p>
<p>A little example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kt" data-lang="kt"><span class="line"><span class="cl"><span class="k">package</span> <span class="nn">io.webcodr.demo</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">import</span> <span class="nn">io.webcodr.demo</span>
</span></span><span class="line"><span class="cl"><span class="k">import</span> <span class="nn">io.kotest.assertions.throwables.shouldThrow</span>
</span></span><span class="line"><span class="cl"><span class="k">import</span> <span class="nn">io.kotest.core.spec.style.FunSpec</span>
</span></span><span class="line"><span class="cl"><span class="k">import</span> <span class="nn">io.mockk.*</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">UserServiceTest</span> <span class="p">:</span> <span class="n">FunSpec</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">private</span> <span class="k">val</span> <span class="py">userRepository</span> <span class="p">=</span> <span class="n">mockk</span><span class="p">&lt;</span><span class="n">UserRepository</span><span class="p">&gt;()</span>
</span></span><span class="line"><span class="cl">    <span class="k">private</span> <span class="k">val</span> <span class="py">service</span> <span class="p">=</span> <span class="n">UserService</span><span class="p">(</span><span class="n">userRepository</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">private</span> <span class="k">lateinit</span> <span class="k">var</span> <span class="py">user</span><span class="p">:</span> <span class="n">User</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">init</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">beforeTest</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">user</span> <span class="p">=</span> <span class="n">User</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s2">&#34;Jane&#34;</span><span class="p">,</span> <span class="s2">&#34;Doe&#34;</span><span class="p">,</span> <span class="s2">&#34;jane@doe.com&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">afterTest</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">clearAllMocks</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">context</span><span class="p">(</span><span class="s2">&#34;getUser()&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">fun</span> <span class="nf">verifyRepoCalls</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">verify</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">userRepository</span><span class="p">.</span><span class="n">findById</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">confirmVerified</span><span class="p">(</span><span class="n">userRepository</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="n">test</span><span class="p">(</span><span class="s2">&#34;should succeed&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">every</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">userRepository</span><span class="p">.</span><span class="n">findById</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span> <span class="n">returns</span> <span class="n">user</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">service</span><span class="p">.</span><span class="n">getUser</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="n">shouldBe</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">verifyRepoCalls</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="n">test</span><span class="p">(</span><span class="s2">&#34;should fail&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">every</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">userRepository</span><span class="p">.</span><span class="n">findById</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span> <span class="n">throws</span> <span class="n">UserNotFoundException</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">shouldThrow</span><span class="p">&lt;</span><span class="n">UserNotFoundException</span><span class="p">&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="n">service</span><span class="p">.</span><span class="n">getUser</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">verifyRepoCalls</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Kotest offers several different styles to write tests. I chose the <code>FunSpec</code> style for this example. You could also use a BDD-like or Jasmine-like style, if you want to.</p>
<p>It’s much more intuitive to nest tests with Kotest. To be fair, JUnit 5 allows you to use <code>@Nested</code> with an inner class to accomplish nesting as well, but it’s not as intuitive and harder to read than trailing lambdas.</p>
<p>Assertions are also a little easier to write. Kotest has over 100 different matchers. You can use them as extension functions, like in the example above or alternatively as infix functions, for example <code>service.getUser(1) shouldBe user</code>. It’s also quite simple to write custom matchers.</p>
<p>There are many more features like soft assertions, tagging, easy temporary file creation or handling for non-deterministic test cases.</p>
<p>For mocking we decided to use MockK, since it’s way more intuitive to use than Mockito with Kotlin. Don’t get me wrong, Mockito is a great library, but it has one flaw: the <code>when</code> method. <code>when</code> is a keyword in Kotlin and to use it with Mockito, you need to write it in backticks. That’s quite ugly and not intuitive at all.</p>
<p>So, in summary, Kotest offers a bunch of pretty neat features and is very intuitive to use. Of course, JUnit can achieve much of this as well, it’s just not that shiny and little harder to read.</p>
<h2 id="the-actual-problem-or-why-the-frak-is-there-intellij-in-the-title"><a href="#the-actual-problem-or-why-the-frak-is-there-intellij-in-the-title" class="heading-anchor">The actual problem or: why the frak is there IntelliJ in the title?</a></h2>
<p>If you migrate an old codebase to Kotlin and want to use Kotest, you will have no choice and have to use JUnit and Kotest in coexistence.</p>
<p>That shouldn’t be a problem, since Kotest uses the JUnit 5 Jupiter engine under the hood. But …</p>
<p>As I wrote a new service in Kotlin and some tests with Kotest, I could not start the JUnit tests anymore. As soon as the maven dependency of Kotest was present, IntelliJ didn’t recognize JUnit tests and used the Kotest files only. With <code>mvn test</code> (Maven Surefire) everything worked fine.</p>
<p>I tried several things and was ready to give up. Search engines didn’t find anything about this problem. Nothing on GitHub, nothing on Stack Overflow.</p>
<p>I hate to give up, so I decided to create a small demo project to open a GitHub issue. Well, that didn’t work out as intended, since the discovery of JUnit tests in the demo project worked fine. The IntelliJ JUnit runner did what it was supposed to: run JUnit and Kotest.</p>
<p>Well, frak. There must be some kind of configuration problem with my real project. I already looked at the IntelliJ runner config, Maven files etc. — nothing worked.</p>
<p>I compared the Maven files from both codebases and there was one difference: my real project did not include the JUnit Jupiter Engine dependency. Bingo. I added it to the Maven file and guess what? It worked like a charm.</p>
<p>What an embarrassment. As we upgraded from JUnit 4 to 5, we forgot to add the new dependency for the engine. I don’t know why the tests worked at all, but it seems the engine is not really necessary for all cases. But it can screw up test discovery quite well, if you forget it.</p>
<p>The dependency configuration in the POM file should look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;groupId&gt;</span>org.junit.jupiter<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;artifactId&gt;</span>junit-jupiter-api<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;version&gt;</span>${junit.version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;scope&gt;</span>test<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;groupId&gt;</span>org.junit.jupiter<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;artifactId&gt;</span>junit-jupiter-engine<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;version&gt;</span>${junit.version}<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;scope&gt;</span>test<span class="nt">&lt;/scope&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/dependency&gt;</span>
</span></span></code></pre></div><p>Well, that was a long post, but IMO it was necessary to show how this problem came to be and even if you have no trouble at all, perhaps you’ll consider using Kotest. It’s awesome!</p>
<h2 id="gradle"><a href="#gradle" class="heading-anchor">Gradle</a></h2>
<p>I’m not sure, but this issue could happen with Gradle as well, when you are migrating to JUnit 5.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Snapshot Tests With Jest</title>
      <link>https://webcodr.io/2018/06/snapshot-tests-with-jest/</link>
      <pubDate>Wed, 13 Jun 2018 16:31:12 +0200</pubDate>
      <guid>https://webcodr.io/2018/06/snapshot-tests-with-jest/</guid>
      <description>Writing tests can sometimes be a tedious task. Mocks and assertions can be a pain in the ass. The latter is especially nasty when HTML is involved. Give me the second p element from the 30th div within an article in aside etc. – no thanks.
The creators of Jest (Facebook) have found a better way: Snapshot tests!
How does it work? Take a look at the following assertion:
it(&#39;should create a foo bar object&#39;, () =&gt; { const result = foo.bar() expect(result).toMatchSnapshot() }) toMatchSnapshot() takes whatever you give to expect(), serializes it and saves it into a file. The next test run will compare the expected value to the stored snapshot and will fail if they don’t match. Jest shows a nicely formatted error message and diff view on failed tests.
</description>
      <content:encoded><![CDATA[<p>Writing tests can sometimes be a tedious task. Mocks and assertions can be a pain in the ass. The latter is especially nasty when HTML is involved. Give me the second p element from the 30th div within an article in aside etc. &ndash; no thanks.</p>
<p>The creators of Jest (Facebook) have found a better way: Snapshot tests!</p>
<h2 id="how-does-it-work"><a href="#how-does-it-work" class="heading-anchor">How does it work?</a></h2>
<p>Take a look at the following assertion:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should create a foo bar object&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">foo</span><span class="p">.</span><span class="nx">bar</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">).</span><span class="nx">toMatchSnapshot</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><p><code>toMatchSnapshot()</code> takes whatever you give to <code>expect()</code>, serializes it and saves it into a file. The next test run will compare the expected value to the stored snapshot and will fail if they don&rsquo;t match. Jest shows a nicely formatted error message and diff view on failed tests.</p>
<p>This is really useful with generated HTML and/or testing UI behaviour. Just call the method and let it compare to the snapshot.</p>
<h2 id="updating-snapshots"><a href="#updating-snapshots" class="heading-anchor">Updating snapshots</a></h2>
<p>You added something to your code and the snapshot has to be updated? No problem:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">jest --updateSnapshot
</span></span></code></pre></div><p>If you&rsquo;re using the Jest watcher it&rsquo;s even simpler. Just press <code>u</code> to update all snapshots or press <code>i</code> to update the snapshots interactively.</p>
<h2 id="what-about-objects-with-generated-values"><a href="#what-about-objects-with-generated-values" class="heading-anchor">What about objects with generated values?</a></h2>
<p>Here&rsquo;s an example with a randomized id:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should fail every time&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">ship</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">id</span><span class="o">:</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">20</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;USS Defiant&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">expect</span><span class="p">(</span><span class="nx">ship</span><span class="p">).</span><span class="nx">toMatchSnapshot</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><p>The id will change on every test run, so this test will fail every time. Well, shit? Nope. Jest got you covered:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should create a ship&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">ship</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">id</span><span class="o">:</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">20</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;USS Defiant&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">expect</span><span class="p">(</span><span class="nx">ship</span><span class="p">).</span><span class="nx">toMatchSnapshot</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">id</span><span class="o">:</span> <span class="nx">expect</span><span class="p">.</span><span class="nx">any</span><span class="p">(</span><span class="nb">Number</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><p>Jest will now only compare the type of the id and the test will pass.</p>
<p>For certain objects like a date, there is another possibility:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="mi">1528902424828</span><span class="p">)</span>
</span></span></code></pre></div><p>A call of <code>Date.now()</code> will call the mock method and always return the same value.</p>
<h2 id="some-advice"><a href="#some-advice" class="heading-anchor">Some advice</a></h2>
<ol>
<li>
<p>Always commit your snapshots! If they are missing, CI systems will always create new snapshots and the tests will become useless.</p>
</li>
<li>
<p>Snapshot tests are an awesome tool, but don&rsquo;t be too lazy. They are no replacement for other assertion types, especially if you&rsquo;re working test-driven. Rather use them alongside your other tests.</p>
</li>
<li>
<p>Write meaningful test names. Well, you heard that one before, didn&rsquo;t you? Really, it helps a lot when tests fail or you have to look inside a snapshot file. Jest takes a test name as an id inside a snapshot file. That&rsquo;s why you have to update a snapshot after changing the name.</p>
</li>
</ol>
]]></content:encoded>
    </item>
    
    <item>
      <title>Awesome tests with Vue and Jest</title>
      <link>https://webcodr.io/2018/04/awesome-tests-with-vue-and-jest/</link>
      <pubDate>Wed, 25 Apr 2018 17:27:26 +0200</pubDate>
      <guid>https://webcodr.io/2018/04/awesome-tests-with-vue-and-jest/</guid>
      <description>Jest is a very neat JavaScript testing library from Facebook. It’s mostly syntax-compatible with Jasmine and needs zero or very little configuration. Code coverage reports are there out-of-the-box and with sandboxed tests and snapshot testing it has some unique features.
Set-up Jest Vue CLI You are using Vue CLI? Consider yourself lucky, the set-up of Jest could not be simpler:
yarn add --dev jest @vue/cli-plugin-unit-jest vue invoke unit-jest Vue CLI will do the rest and also create an example spec for the HelloWorld component.
</description>
      <content:encoded><![CDATA[<p>Jest is a very neat JavaScript testing library from Facebook. It&rsquo;s mostly syntax-compatible with Jasmine and needs zero
or very little configuration. Code coverage reports are there out-of-the-box and with sandboxed tests and snapshot testing
it has some unique features.</p>
<h2 id="set-up-jest"><a href="#set-up-jest" class="heading-anchor">Set-up Jest</a></h2>
<h3 id="vue-cli"><a href="#vue-cli" class="heading-anchor">Vue CLI</a></h3>
<p>You are using Vue CLI? Consider yourself lucky, the set-up of Jest could not be simpler:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">yarn add --dev jest @vue/cli-plugin-unit-jest
</span></span><span class="line"><span class="cl">vue invoke unit-jest
</span></span></code></pre></div><p>Vue CLI will do the rest and also create an example spec for the HelloWorld component.</p>
<h3 id="diy"><a href="#diy" class="heading-anchor">DIY</a></h3>
<p>Install all necessary dependencies:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">yarn add --dev @vue/test-utils babel-jest jest jest-serializer-vue vue-jest
</span></span></code></pre></div><p>Create <code>jest.config.js</code> in your project root directory:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">moduleFileExtensions</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;js&#39;</span><span class="p">,</span> <span class="s1">&#39;json&#39;</span><span class="p">,</span> <span class="s1">&#39;vue&#39;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nx">transform</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;^.+\\.vue$&#39;</span><span class="o">:</span> <span class="s1">&#39;vue-jest&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;^.+\\.js?$&#39;</span><span class="o">:</span> <span class="s1">&#39;babel-jest&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">moduleNameMapper</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;^@/(.*)$&#39;</span><span class="o">:</span> <span class="s1">&#39;&lt;rootDir&gt;/src/$1&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">snapshotSerializers</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;jest-serializer-vue&#39;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nx">testMatch</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;&lt;rootDir&gt;/src/tests/**/*.spec.js&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Please adjust the paths in <code>moduleNameMapper</code> and <code>testMatch</code> to your project.</p>
<p>You should also add a modern JavaScript preset to your <code>.babelrc</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;presets&#34;</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;es2015&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h4 id="optional-step"><a href="#optional-step" class="heading-anchor">Optional step</a></h4>
<p>Add the following line to your <code>.gitignore</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">/coverage
</span></span></code></pre></div><p>The set-up is now complete. Let&rsquo;s write a test file!</p>
<h2 id="writing-tests"><a href="#writing-tests" class="heading-anchor">Writing tests</a></h2>
<p>Here is a little example Vue component:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">ul</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;demo&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;demo__item&#34;</span> <span class="na">v-for</span><span class="o">=</span><span class="s">&#34;value in values&#34;</span> <span class="na">:key</span><span class="o">=</span><span class="s">&#34;value&#34;</span><span class="p">&gt;</span>{{ value }}<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">values</span><span class="o">:</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">created</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">fetchValues</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">async</span> <span class="nx">fetchValues</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">&#39;/api/demo/values&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="k">this</span><span class="p">.</span><span class="nx">values</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The component <code>Demo</code> will fetch some values after its creation and display them in an unordered list. This example is quite
simple, but testing is a little more complex due to the usage of <code>fetch</code>, <code>async</code> and <code>await</code>.</p>
<p>Of course, there are some tools to help us:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">yarn add --dev fetch-mock flush-promises
</span></span></code></pre></div><p>Now, let&rsquo;s write a test:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">shallow</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@vue/test-utils&#39;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">fetchMock</span> <span class="nx">from</span> <span class="s1">&#39;fetch-mock&#39;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">flushPromises</span> <span class="nx">from</span> <span class="s1">&#39;flush-promises&#39;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Demo</span> <span class="nx">from</span> <span class="s1">&#39;@/components/Demo.vue&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">values</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="s1">&#39;foo&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s1">&#39;bar&#39;</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">describe</span><span class="p">(</span><span class="s1">&#39;Demo.vue&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">beforeEach</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">fetchMock</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/api/demo/values&#39;</span><span class="p">,</span> <span class="nx">values</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;renders component&#39;</span><span class="p">,</span> <span class="kr">async</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">wrapper</span> <span class="o">=</span> <span class="nx">shallow</span><span class="p">(</span><span class="nx">Demo</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="kr">await</span> <span class="nx">flushPromises</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">expect</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">.</span><span class="nx">vm</span><span class="p">.</span><span class="nx">values</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="nx">values</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">afterEach</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">fetchMock</span><span class="p">.</span><span class="nx">restore</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><h3 id="whats-going-on"><a href="#whats-going-on" class="heading-anchor">What&rsquo;s going on?</a></h3>
<ol>
<li>
<p><code>shallow</code> from Vue Test Utils creates a wrapper of the rendered and mounted component, any child components will be stubs.
If you need child components in your test, please use <code>mount</code> instead of <code>shallow</code>.</p>
</li>
<li>
<p><code>fetchMock</code> will create a mocked version of the Fetch API. In this case it will return the defined values for a GET request to
<code>/api/demo/values</code>. If you send a request that&rsquo;s not defined in fetchMock, it will throw an exception and break your tests.</p>
</li>
<li>
<p>The test itself is defined as async to use <code>await</code> for <code>flushPromises()</code>. It will wait until the mocked request is finished and the values are stored in the component&rsquo;s data.</p>
</li>
<li>
<p>You can now access the data property <code>values</code> and compare the content to the response of the mocked HTTP request.</p>
</li>
</ol>
<h2 id="conclusion"><a href="#conclusion" class="heading-anchor">Conclusion</a></h2>
<p>Setting up Jest for Vue is easy, even if you have to do it manually.</p>
<p><strong>A little warning</strong>: setting up Jest for an existing app can be tedious.
The current AngularJS app of our customer can&rsquo;t be tested with Jest, at least for now. The AngularJS HTTP mock does not work and I haven&rsquo;t figured out the problem yet.</p>
<p>But enough of Angular: the real deal comes with the testing itself. Async/await is a nice and simple way for testing asynchronous behaviour.
I don&rsquo;t think this could be easier and it&rsquo;s a reliable method with the power of modern JavaScript. Try to imagine what the demo test would look like in ES5 &hellip;</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
