{"componentChunkName":"component---src-templates-blog-post-js","path":"/snapshot-testing-angular-applications/","result":{"data":{"site":{"siteMetadata":{"title":"Fabrizio Fortunato","author":"Fabrizio Fortunato","siteUrl":"https://izifortune.com"}},"markdownRemark":{"id":"bf864f86-a192-5d8b-a42b-3c3c3ebe2134","excerpt":"In one of my previous articles, I’ve explored how we can start unit testing Angular applications with Jest. Now its time to introduce another exciting feature…","html":"<p>In one of my previous <a href=\"https://izifortune.com/unit-testing-angular-applications-with-jest/\">articles</a>, I’ve explored how we can start unit testing Angular applications with Jest. Now its time to introduce another exciting feature that Jest provides us: <strong><em>Snapshot Testing</em></strong>.</p>\n<h2>Intro</h2>\n<p>One of the main advantages of using <em>Jest</em> over <em>Karma + Jasmine</em> is the significant decrease in execution time for the unit tests. What if Jest allows us to decrease, not only, execution time but also the actual writing time of a unit test?</p>\n<p>Welcome to snapshot testing.</p>\n<p>As the name suggests it, snapshot testing takes any serialisable object, create a snapshot and then compare your changes with the previously taken snapshot. <em>Jest</em> support out of the box snapshot testing an example of a simple snapshot test can be the following:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token function\">describe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'FlightService'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Should return a list of flights'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> flights <span class=\"token operator\">=</span> FlightService<span class=\"token punctuation\">.</span><span class=\"token function\">list</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>flights<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toMatchSnapshot</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Upon test execution, <em>Jest</em> takes your object, serialise it into a string, save the representation into a file like the following:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">// Jest Snapshot v1, https://goo.gl/fbAQLP</span>\n\nexports<span class=\"token punctuation\">[</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">FlightService Should return a list of flights 1</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">\nArray [\n  Object {\n    \"arrivalDatetime\": \"2018-06-15T21:00:00\",\n    \"departure\": \"DUB\",\n    \"departureDatetime\": \"2018-06-15T17:25:00\",\n    \"destination\": \"WRO\",\n    \"flightNumber\": \"FR153\",\n  },\n  Object {\n    \"arrivalDateteim\": \"2018-06-16T20:35:00\",\n    \"departure\": \"DUB\",\n    \"departureDatetime\": \"2018-06-16T16:30:00\",\n    \"destination\": \"CIA\",\n    \"flightNumber\": \"FR154\",\n  },\n  Object {\n    \"arrivalDatetime\": \"2018-06-15T20:55:00\",\n    \"departure\": \"DUB\",\n    \"departureDatetime\": \"2018-06-18T17:15:00\",\n    \"destination\": \"MAD\",\n    \"flightNumber\": \"FR155\",\n  },\n]\n</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Any other execution of the test is compared to the current object snapshot with the previous one stored in the file. The whole functionality boils down to string comparison between the two snapshots. While using snapshot testing, <em>Jest</em> compares the current snapshots with the previous version. That’s why it is necessary to commit the snapshots files along with your test files.</p>\n<p>When using snapshot testing, we have to get it right the first time. We are creating the <em>gold standard</em> test, and we have to treat it as the most accurate test possible.</p>\n<h2>When</h2>\n<p>In the <em>React</em> ecosystem, snapshot testing is recommended primarily for UI components, where you can quickly render components leveraging <em>jsdom</em>.\nSnapshot testing can be used alongside unit testing or in some cases also replace it entirely.\nThe decision is related to the status of your project. If your current project doesn’t much testing coverage than snapshot testing can be a way to increase coverage without any pain; on the other hand, if a project has already a high unit test coverage than you can use it as support testing to perform regression testing.</p>\n<h2>ng-world</h2>\n<p>Snapshot testing is not only available in the <em>React</em> world. We can use and apply snapshot testing in an <em>Angular</em> application also.</p>\n<p>I assume that your application is already configured for using <em>Jest</em>, if not you can check out my previous <a href=\"https://izifortune.com/unit-testing-angular-applications-with-jest/\">article</a>.</p>\n<p>An <em>Angular</em> application is a collection of components, directives, services and pipes which combined make a module. <em>Angular</em> makes it easy to test any element of your application, and we can apply snapshot testing to each of those elements.</p>\n<h3>Component</h3>\n<p>In an <em>Angular</em> component there are few parts that we can unit test:</p>\n<ul>\n<li>Public methods of a component</li>\n<li>Template rendering</li>\n<li>Input/Output</li>\n</ul>\n<p>Snapshot testing can cover all those different parts and at the same time speed up your test creation and coverage.</p>\n<p>Let’s take the following <code class=\"language-text\">FlightInfoComponent</code> used to display informations about a selected flight:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> Input<span class=\"token punctuation\">,</span> Component <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@angular/core'</span><span class=\"token punctuation\">;</span>\n\n@<span class=\"token function\">Component</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  selector<span class=\"token operator\">:</span> <span class=\"token string\">'flight-info'</span><span class=\"token punctuation\">,</span>\n  template<span class=\"token operator\">:</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">\n&lt;mat-list-item>\n  &lt;div class=\"fare\">\n    &lt;span class=\"airport\">{{ flight.departure }}&lt;/span>\n    &lt;small>{{ flight.departureDatetime | date:'short' }}&lt;/small>\n  &lt;/div>\n  &lt;div class=\"fare\"> \n    &lt;span class=\"airport\">{{ flight.destination }}&lt;/span>\n    &lt;small>{{ flight.arrivalDatetime | date:'short' }}&lt;/small>\n  &lt;/div>\n&lt;/mat-list-item>\n  </span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">,</span>\n  styleUrls<span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span> <span class=\"token string\">'./flight-info.component.css'</span> <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">FlightInfoComponent</span>  <span class=\"token punctuation\">{</span>\n  @<span class=\"token function\">Input</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> flight<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The <code class=\"language-text\">FlightInfoComponent</code> is a dumb component, it doesn’t hold any logic, and its only concern is displaying information received as <code class=\"language-text\">@Input</code>. What is necessary to test here is that the information is displayed correctly, like a pure function, given a specific input we are expecting the same output.</p>\n<p>Snapshot testing shines in this scenarios. The component fixture is a serialisable object; therefore, we can snapshot it.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Should display a flight'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> fixture <span class=\"token operator\">=</span> TestBed<span class=\"token punctuation\">.</span><span class=\"token function\">createComponent</span><span class=\"token punctuation\">(</span>FlightInfoComponent<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>fixture<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toMatchSnapshot</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>We can now pass data as <code class=\"language-text\">@Input</code> for <code class=\"language-text\">FlightInfoComponent</code> and generate a snapshot that ensures our component UI is predictable.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Should display a flight from DUB to WRO'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    component<span class=\"token punctuation\">.</span>flight <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n      flightNumber<span class=\"token operator\">:</span> <span class=\"token string\">'FR153'</span><span class=\"token punctuation\">,</span>\n      departure<span class=\"token operator\">:</span> <span class=\"token string\">'DUB'</span><span class=\"token punctuation\">,</span>\n      destination<span class=\"token operator\">:</span> <span class=\"token string\">'WRO'</span><span class=\"token punctuation\">,</span>\n      departureDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-15T17:25:00'</span><span class=\"token punctuation\">,</span>\n      arrivalDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-15T21:00:00'</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    fixture<span class=\"token punctuation\">.</span><span class=\"token function\">detectChanges</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>fixture<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toMatchSnapshot</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The snapshot created will be the following:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">exports<span class=\"token punctuation\">[</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">FlightInfoComponent Should display a flight from DUB to WRO 1</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">\n&lt;flight-info\n  flight={[Function Object]}\n>\n  &lt;mat-list-item\n    class=\"mat-list-item\"\n  >\n    &lt;div\n      class=\"mat-list-item-content\"\n    >\n      &lt;div\n        class=\"mat-list-item-ripple mat-ripple\"\n        mat-ripple=\"\"\n        ng-reflect-disabled=\"true\"\n        ng-reflect-trigger=\"[object HTMLUnknownElement]\"\n      />\n      &lt;div\n        class=\"mat-list-text\"\n      />\n      &lt;div\n        class=\"fare\"\n      >\n        &lt;span\n          class=\"airport\"\n        >\n          DUB\n        &lt;/span>\n        &lt;small>\n          6/15/18, 5:25 PM\n        &lt;/small>\n      &lt;/div>\n      &lt;div\n        class=\"fare\"\n      >\n        &lt;span\n          class=\"airport\"\n        >\n          WRO\n        &lt;/span>\n        &lt;small>\n          6/15/18, 9:00 PM\n        &lt;/small>\n      &lt;/div>\n    &lt;/div>\n  &lt;/mat-list-item>\n&lt;/flight-info>\n</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>We can notice that the template of our component is rendered correctly, displaying the information about our flight.</p>\n<h3>Service/Pipe</h3>\n<p>After components, we can apply snapshot testing to services and pipes. The concept is the same that we use for components with the exception that we can omit <em>TestBed</em>. Services and pipes are javascript classes and TestBed is only used for handling the dependencies, which can be easily mocked, for unit tests, when invoking the constructor of such classes.</p>\n<p>I’m grouping services and pipes because the approach to testing is the same.</p>\n<p>Let’s define our <code class=\"language-text\">FlightListService</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> Injectable <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@angular/core'</span><span class=\"token punctuation\">;</span>\n\n@<span class=\"token function\">Injectable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">FlightListService</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">public</span> <span class=\"token function\">list</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">[</span>\n      <span class=\"token punctuation\">{</span> flightNumber<span class=\"token operator\">:</span> <span class=\"token string\">'FR153'</span><span class=\"token punctuation\">,</span> departure<span class=\"token operator\">:</span> <span class=\"token string\">'DUB'</span><span class=\"token punctuation\">,</span> destination<span class=\"token operator\">:</span> <span class=\"token string\">'WRO'</span><span class=\"token punctuation\">,</span> departureDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-15T17:25:00'</span><span class=\"token punctuation\">,</span> arrivalDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-15T21:00:00'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n      <span class=\"token punctuation\">{</span> flightNumber<span class=\"token operator\">:</span> <span class=\"token string\">'FR153'</span><span class=\"token punctuation\">,</span> departure<span class=\"token operator\">:</span> <span class=\"token string\">'WRO'</span><span class=\"token punctuation\">,</span> destination<span class=\"token operator\">:</span> <span class=\"token string\">'DUB'</span><span class=\"token punctuation\">,</span> departureDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-15T21:25:00'</span><span class=\"token punctuation\">,</span> arrivalDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-15T23:05:00'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n      <span class=\"token punctuation\">{</span> flightNumber<span class=\"token operator\">:</span> <span class=\"token string\">'FR154'</span><span class=\"token punctuation\">,</span> departure<span class=\"token operator\">:</span> <span class=\"token string\">'DUB'</span><span class=\"token punctuation\">,</span> destination<span class=\"token operator\">:</span> <span class=\"token string\">'CIA'</span><span class=\"token punctuation\">,</span> departureDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-16T16:30:00'</span><span class=\"token punctuation\">,</span> arrivalDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-16T20:35:00'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n      <span class=\"token punctuation\">{</span> flightNumber<span class=\"token operator\">:</span> <span class=\"token string\">'FR154'</span><span class=\"token punctuation\">,</span> departure<span class=\"token operator\">:</span> <span class=\"token string\">'CIA'</span><span class=\"token punctuation\">,</span> destination<span class=\"token operator\">:</span> <span class=\"token string\">'DUB'</span><span class=\"token punctuation\">,</span> departureDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-16T21:00:00'</span><span class=\"token punctuation\">,</span> arrivalDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-16T23:15:00'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n      <span class=\"token punctuation\">{</span> flightNumber<span class=\"token operator\">:</span> <span class=\"token string\">'FR155'</span><span class=\"token punctuation\">,</span> departure<span class=\"token operator\">:</span> <span class=\"token string\">'DUB'</span><span class=\"token punctuation\">,</span> destination<span class=\"token operator\">:</span> <span class=\"token string\">'MAD'</span><span class=\"token punctuation\">,</span> departureDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-18T17:15:00'</span><span class=\"token punctuation\">,</span> arrivalDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-15T20:55:00'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n      <span class=\"token punctuation\">{</span> flightNumber<span class=\"token operator\">:</span> <span class=\"token string\">'FR155'</span><span class=\"token punctuation\">,</span> departure<span class=\"token operator\">:</span> <span class=\"token string\">'MAD'</span><span class=\"token punctuation\">,</span> destination<span class=\"token operator\">:</span> <span class=\"token string\">'DUB'</span><span class=\"token punctuation\">,</span> departureDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-18T21:30:00'</span><span class=\"token punctuation\">,</span> arrivalDatetime<span class=\"token operator\">:</span> <span class=\"token string\">'2018-06-15T23:10:00'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span> \n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">public</span> <span class=\"token function\">single</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">departure<span class=\"token punctuation\">,</span> destination</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> flight <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">list</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">el</span> <span class=\"token operator\">=></span>\n      <span class=\"token punctuation\">(</span>el<span class=\"token punctuation\">.</span>departure <span class=\"token operator\">===</span> departure <span class=\"token operator\">&amp;&amp;</span>\n        el<span class=\"token punctuation\">.</span>destination <span class=\"token operator\">===</span> destination<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> flight <span class=\"token operator\">?</span> flight<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">:</span> <span class=\"token keyword\">undefined</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>So now start testing one of the public methods available in the service.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> FlightListService <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./FlightListService'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">describe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'FlightListService'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> service<span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>  \n    service <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">FlightListService</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Should return a single fligth'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>service<span class=\"token punctuation\">.</span><span class=\"token function\">single</span><span class=\"token punctuation\">(</span><span class=\"token string\">'DUB'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'MAD'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toMatchSnapshot</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>In a real-world application the <code class=\"language-text\">FlightListService</code>, rather than returning a hardcoded list of flights, will contact an API to get the list of all the available flights.</p>\n<p>Our list method can be rewritten as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">public</span> <span class=\"token function\">listAPI</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>$http<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span>\n      <span class=\"token string\">'https://murmuring-ocean-10826.herokuapp.com/en/api/2/flights/from/DUB/to/STN/2014-12-02/2015-02-02/250/unique/?limit=15&amp;offset-0'</span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>There are two choices now for testing the <em>list</em> method. We can proceed to mock the HTTP call and returned some values during the test. Alternatively, another option is to continue doing the HTTP call and get the value directly from a real service.</p>\n<p>Choosing the first option let the test fall into unit tests since we are testing the method in isolation. We can easily mock dependencies by using jest <a href=\"https://facebook.github.io/jest/docs/en/mock-function-api.html\">mock functions</a></p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token function\">describe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'FlightListService'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> service<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> http <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>  \n    <span class=\"token keyword\">get</span><span class=\"token operator\">:</span> jest<span class=\"token punctuation\">.</span><span class=\"token function\">fn</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    service <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">FlightListService</span><span class=\"token punctuation\">(</span>\n      http <span class=\"token keyword\">as</span> any\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Should return all the routes from API'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>service<span class=\"token punctuation\">.</span><span class=\"token function\">listAPI</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toMatchSnapshot</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The previous test, using mocking values, doesn’t add much value to our test suite. We are testing a tautology, given that we are not doing anything with the data returned.</p>\n<p>The second option that we have is to use snapshot testing for integration tests. We are testing functionality spanning across multiple units. We cannot mock <em>HttpClient</em> now since we want our test make the actual API call.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> TestBed <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@angular/core/testing'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> HttpClientModule <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@angular/common/http'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> FlightListService <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./flight-list.service'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">describe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'FlightListService Integration tests'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> service<span class=\"token operator\">:</span> FlightListService<span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    TestBed<span class=\"token punctuation\">.</span><span class=\"token function\">configureTestingModule</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      imports<span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>HttpClientModule<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n      providers<span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>FlightListService<span class=\"token punctuation\">]</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    service <span class=\"token operator\">=</span> TestBed<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span>FlightListService<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Should return all the routes from API'</span><span class=\"token punctuation\">,</span> <span class=\"token parameter\">done</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    service<span class=\"token punctuation\">.</span><span class=\"token function\">listAPI</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">subscribe</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">res</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>res<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toMatchSnapshot</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token function\">done</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The integration test checks that the API is not changing or breaking the contract of the response, giving our application an extra safety measure especially when you are not in control of the API.</p>\n<h3>NGRX</h3>\n<p>If you are developing a medium/big <em>Angular</em> application chances are that you are using <a href=\"https://github.com/ngrx/platform\">NGRX</a> for managing your state. By convention, the top-level state is an object or some other key-value collection like a Map, but technically it can be any type. Still, you should do your best to keep the state serialisable. Don’t put anything inside it that you can’t easily turn into JSON.</p>\n<p>The previous is an extract from <em>reduxjs</em> documentation. The state in redux is a serialisable object that we can test using snapshot testing.</p>\n<p>Let’s take the common counter reducer example and apply snapshot test to it.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> counter<span class=\"token operator\">:</span> ActionReducer<span class=\"token operator\">&lt;</span>number<span class=\"token operator\">></span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">state<span class=\"token operator\">:</span> number <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> action<span class=\"token operator\">:</span> Action</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">switch</span><span class=\"token punctuation\">(</span>action<span class=\"token punctuation\">.</span>type<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">case</span> <span class=\"token string\">'INCREMENT'</span><span class=\"token operator\">:</span>\n            <span class=\"token keyword\">return</span> state <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">case</span> <span class=\"token string\">'DECREMENT'</span><span class=\"token operator\">:</span>\n            <span class=\"token keyword\">return</span> state <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">default</span><span class=\"token operator\">:</span>\n            <span class=\"token keyword\">return</span> state<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span>counter<span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">\"./counter\"</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">describe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'The counter reducer'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'should return current state when an invalid action is dispatched'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">const</span> actual <span class=\"token operator\">=</span> <span class=\"token function\">counter</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>type<span class=\"token operator\">:</span> <span class=\"token string\">'INVALID_ACTION'</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>actual<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toMatchSnapshot</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token operator\">...</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h2>snapshot failed</h2>\n<p>Testing, in general, improve the quality of our application and let us feel more comfortable while making new changes, that we are not breaking any existing functionality. We write tests because our application changes over time and we want to make sure that we don’t break previous functionalities.</p>\n<p>We have explored how to create snapshots for different elements of our Angular application what is missing now is how to update the snapshots if something has changed in our code.\nThere is a command:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> run jest -- -u</code></pre></div>\n<p>The command updates all the snapshots to the current version of your objects, ignoring and discarding the previous one. Don’t forget to commit once again the updated snapshots.</p>\n<p>You can find all the examples used in the article in\n<a href=\"https://stackblitz.com/edit/angular-snapshot-testing\">https://stackblitz.com/edit/angular-snapshot-testing</a> feel free to clone it and start exploring snapshot testing.</p>","frontmatter":{"title":"Snapshot testing Angular applications","date":"July 02, 2018","description":null,"socialImage":{"childImageSharp":{"fixed":{"src":"/dist/static/88fc993698200a96f2782641532f8e54/048fd/jest-angular-3.png"}}},"image":{"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsSAAALEgHS3X78AAAA6ElEQVQY02PQLT+OhvRLjwbGr5hoXLSPxapPPirCd6pJ8UFMZUDEgKKt7KhK7flOy4qnDBovOQ0fWMVfMw67puI5RyJQr4Kg5tKjynUXus3LXjBo3BZweJzSdLNswmVVrwWi3jqVJ4nQXH+h0LH9paTzy7SWlw0z7jbOvK4f1K0cr1F3Xq/sGCHNDRcTvCd/UPV8WTzhjl3SGfesu/r+jXqZSo1X9EuP4NMMNFuj+oxT6qYTCkEfLaLv6wSfE7U9wKQXEzRDtfY80Gh8miH6NatOm+bt7bSuOshp260S75y2EWgippuBCAA+FcIU366YUwAAAABJRU5ErkJggg==","aspectRatio":2.737704918032787,"src":"/dist/static/2d5de7a09e3e1bf6c4feaa5eb6864a47/a5924/jest-angular-4.png","srcSet":"/dist/static/2d5de7a09e3e1bf6c4feaa5eb6864a47/17cc0/jest-angular-4.png 167w,\n/dist/static/2d5de7a09e3e1bf6c4feaa5eb6864a47/f7869/jest-angular-4.png 333w,\n/dist/static/2d5de7a09e3e1bf6c4feaa5eb6864a47/a5924/jest-angular-4.png 666w","sizes":"(max-width: 666px) 100vw, 666px"}}}}}},"pageContext":{"slug":"/snapshot-testing-angular-applications/","previous":{"fields":{"slug":"/performance-budgets-with-lighthouse-lighthouse-keeper/"},"frontmatter":{"title":"Performance budgets with Lighthouse - Lighthouse keeper"}},"next":{"fields":{"slug":"/angular-polyfill-strategies/"},"frontmatter":{"title":"Angular polyfill strategies"}}}}}