{"componentChunkName":"component---src-templates-blog-post-js","path":"/unit-testing-angular-applications-with-jest/","result":{"data":{"site":{"siteMetadata":{"title":"Fabrizio Fortunato","author":"Fabrizio Fortunato","siteUrl":"https://izifortune.com"}},"markdownRemark":{"id":"55a552e2-be80-57f7-a211-38fda93f72a6","excerpt":"Let’s discuss about unit testing in Angular, this will be just an introduction on Angular unit testing and what are the benefits of adopting Jest as test runner…","html":"<p>Let’s discuss about unit testing in Angular, this will be just an introduction on Angular unit testing and what are the benefits of adopting <a href=\"https://facebook.github.io/jest/\">Jest</a> as test runner and suite for your execution.</p>\n<h3>What?</h3>\n<p><em>Jest</em> is an integrated testing solution written by Facebook and famous especially in the <em>React</em> world.</p>\n<p>The key features of <em>Jest</em> are:</p>\n<ul>\n<li>Easy setup</li>\n<li>Instant feedback</li>\n<li>Powerful mocking</li>\n<li>Works with typescript</li>\n<li>Snapshot testing</li>\n</ul>\n<p>Easy setup meaning that you need almost zero configuration to get started.</p>\n<p>Instant feedback because he will run only the test files related to the changes.</p>\n<p>Powerful mocking through easy to use mock functions</p>\n<h3>Why?</h3>\n<p>The first reason why you want to start using jest is speed.</p>\n<p>Unit test should run fast </p>\n<p>Comparing brand new application crated with the <code class=\"language-text\">@angular/cli</code></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/dist/static/3543116d18d52c64c425d58c17a5dad7/a4b11/chrome.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 21.62162162162162%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAAsSAAALEgHS3X78AAAAl0lEQVQI1y1OixLDIAjzP7auteIDBKq3/f+3LZ27y8WAEBJ8TFG3a1TuKVcqDXwSxR+o5JQp5XISmiWmHKn8RcqhO6s3sabO86M22IbP9/SJ5xJVUevm3K00gTWAZRyAY7Ax1B1DlbmJNFks3BnAQq4M4M5x0jq4xwQNDviAE5U78IGI5Y6HZqK67DH32PZtj8/XsQC9yi/KpyQTjSm58gAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"karma-chrome\"\n        title=\"karma-chrome\"\n        src=\"/dist/static/3543116d18d52c64c425d58c17a5dad7/102e5/chrome.png\"\n        srcset=\"/dist/static/3543116d18d52c64c425d58c17a5dad7/83276/chrome.png 148w,\n/dist/static/3543116d18d52c64c425d58c17a5dad7/ba02f/chrome.png 295w,\n/dist/static/3543116d18d52c64c425d58c17a5dad7/102e5/chrome.png 590w,\n/dist/static/3543116d18d52c64c425d58c17a5dad7/74549/chrome.png 885w,\n/dist/static/3543116d18d52c64c425d58c17a5dad7/7213b/chrome.png 1180w,\n/dist/static/3543116d18d52c64c425d58c17a5dad7/a4b11/chrome.png 2560w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p><strong><em>karma-chrome</em></strong>: 14.911s</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/dist/static/0160421d22ecea24029c029e5427fc15/a4b11/phantomjs-1.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 21.62162162162162%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAAsSAAALEgHS3X78AAAAmElEQVQI1yWOCw7DIAxDe4+tY5RfSEj47P53m0ulJ2Q5JvHR5xQ1G6tUiZlSqTGXK0YfIt6QYsggXzGHVHxIEJtbHM1YlMRIB89fs8nNtK/Z1xhr2ZgkwmrEjZti+/MZwvlw9DlElViImbgiUyqotdVttkyMOojiLPheEUCczh+YoQ/GAFbYux8T65+qr9MhCt6f77m5hfN/6qQkUA8QUc0AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"karma-phantomjs\"\n        title=\"karma-phantomjs\"\n        src=\"/dist/static/0160421d22ecea24029c029e5427fc15/102e5/phantomjs-1.png\"\n        srcset=\"/dist/static/0160421d22ecea24029c029e5427fc15/83276/phantomjs-1.png 148w,\n/dist/static/0160421d22ecea24029c029e5427fc15/ba02f/phantomjs-1.png 295w,\n/dist/static/0160421d22ecea24029c029e5427fc15/102e5/phantomjs-1.png 590w,\n/dist/static/0160421d22ecea24029c029e5427fc15/74549/phantomjs-1.png 885w,\n/dist/static/0160421d22ecea24029c029e5427fc15/7213b/phantomjs-1.png 1180w,\n/dist/static/0160421d22ecea24029c029e5427fc15/a4b11/phantomjs-1.png 2560w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span>\n<strong><em>karma-phantomjs</em></strong>: 13.119s</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/dist/static/de5f206042ea13d515f60a5135656d80/a4b11/jest.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 30.405405405405407%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsSAAALEgHS3X78AAAAhElEQVQY05WQyw3DMAxDM0g/+diybEW2HCNFe+gIPXT/ZUogA8QFeCAEPJDi0GrWrKJlnN3saPEB5nqfejR8vm/btpiU0woBvtzGXpjYt/2Rra25ZqtaDHwvHEWJBaks7ENE5z9q789XiFKqcUqAcULtQ+cwpoqCbxVrOWLidJhp8af8D5iFMPdnT7CnAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"jest\"\n        title=\"jest\"\n        src=\"/dist/static/de5f206042ea13d515f60a5135656d80/102e5/jest.png\"\n        srcset=\"/dist/static/de5f206042ea13d515f60a5135656d80/83276/jest.png 148w,\n/dist/static/de5f206042ea13d515f60a5135656d80/ba02f/jest.png 295w,\n/dist/static/de5f206042ea13d515f60a5135656d80/102e5/jest.png 590w,\n/dist/static/de5f206042ea13d515f60a5135656d80/74549/jest.png 885w,\n/dist/static/de5f206042ea13d515f60a5135656d80/7213b/jest.png 1180w,\n/dist/static/de5f206042ea13d515f60a5135656d80/a4b11/jest.png 2560w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p><strong><em>jest</em></strong>: 4.970s</p>\n<p>That’s 8.606 seconds difference between the two runs, karma-chrome are taking more than double the time to execute just 1 suite and 3 tests.</p>\n<p>I’m including <em>PhantomJS</em> in these comparison even if its not supported <a href=\"https://news.ycombinator.com/item?id=14105489\">anymore</a>, mainly because its probably the fastest option for running tests in a CI environment ( Jenkins, Travis )</p>\n<p><em>Jest</em> doesn’t need an actual browser ( headless or not ) to run the test ( there are some drawbacks ). If you are looking for a replacement in Continuous Integration environments for <em>PhantomJS</em> you can quickly switch to <em>Jest</em> without the need of any configuration on your CI.</p>\n<p>It is based upon <em>Jasmine</em> which is probably the default framework for <em>Angular</em> applications and its included in the CLI.</p>\n<h3>How?</h3>\n<p>The first step is to install jest on your new project:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">yarn</span> <span class=\"token function\">add</span> -D @types/jest jest jest-preset-angular</code></pre></div>\n<p>Installing the types necessary for typescript compiler, the framework itself and in the <code class=\"language-text\">jest-preset-angular</code> which contains a configuration for Angular project.</p>\n<p>Next step, modify the <code class=\"language-text\">package.json</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\">  <span class=\"token property\">\"scripts\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"ng\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"ng\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"start\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"ng serve\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"build\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"ng build\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"lint\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"ng lint\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"e2e\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"ng e2e\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"test\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"jest\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"test:watch\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"jest --watch\"</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"jest\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token property\">\"preset\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"jest-preset-angular\"</span><span class=\"token punctuation\">,</span>\n\t<span class=\"token property\">\"setupTestFrameworkScriptFile\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"&lt;rootDir>/src/jest.ts\"</span>\n  <span class=\"token punctuation\">}</span></code></pre></div>\n<p>I’m changing the npm scripts that will execute jest framework and adding the only configuration ( almost zero config ) that we need for the project.</p>\n<p>I’m requiring  <code class=\"language-text\">&quot;setupTestFrameworkScriptFile&quot;: &quot;&lt;rootDir&gt;/src/jest.ts&quot;</code> we need then to create this file that Jest will use to startup inside the src folder of the project.</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 string\">'jest-preset-angular'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token string\">'./jest-global-mocks'</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The last step, since <em>Jest</em> doesn’t run a real browser but its based upon <em>jsdom</em>, its to provide mocks for browser specific API like <code class=\"language-text\">localStorage</code> etc:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">mock</span> <span class=\"token operator\">=</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> storage <span class=\"token operator\">=</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 function-variable function\">getItem</span><span class=\"token operator\">:</span> <span class=\"token parameter\">key</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>key <span class=\"token keyword\">in</span> storage <span class=\"token operator\">?</span> storage<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span> <span class=\"token operator\">:</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n\t\t   <span class=\"token function-variable function\">setItem</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">key<span class=\"token punctuation\">,</span> value</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>storage<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> value <span class=\"token operator\">||</span> <span class=\"token string\">''</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n\t\t   <span class=\"token function-variable function\">removeItem</span><span class=\"token operator\">:</span> <span class=\"token parameter\">key</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">delete</span> storage<span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n\t\t   <span class=\"token function-variable function\">clear</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>storage <span class=\"token operator\">=</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>\n\nObject<span class=\"token punctuation\">.</span><span class=\"token function\">defineProperty</span><span class=\"token punctuation\">(</span>window<span class=\"token punctuation\">,</span> <span class=\"token string\">'localStorage'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> value<span class=\"token operator\">:</span> <span class=\"token function\">mock</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nObject<span class=\"token punctuation\">.</span><span class=\"token function\">defineProperty</span><span class=\"token punctuation\">(</span>window<span class=\"token punctuation\">,</span> <span class=\"token string\">'sessionStorage'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> value<span class=\"token operator\">:</span> <span class=\"token function\">mock</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nObject<span class=\"token punctuation\">.</span><span class=\"token function\">defineProperty</span><span class=\"token punctuation\">(</span>window<span class=\"token punctuation\">,</span> <span class=\"token string\">'getComputedStyle'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n<span class=\"token function-variable function\">value</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">[</span><span class=\"token string\">'-webkit-appearance'</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>Last but not least we have to remove <code class=\"language-text\">@types/jasmine</code> from node_modules and make sure you include jest as the new types in the tsconfig.spec.json</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n  <span class=\"token property\">\"extends\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"../tsconfig.json\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"compilerOptions\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"outDir\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"../out-tsc/spec\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"baseUrl\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"./\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"module\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"commonjs\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"target\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"es5\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token property\">\"types\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n      <span class=\"token string\">\"jest\"</span><span class=\"token punctuation\">,</span>\n      <span class=\"token string\">\"node\"</span>\n    <span class=\"token punctuation\">]</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"include\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token string\">\"**/*.spec.ts\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token string\">\"**/*.d.ts\"</span>\n  <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>Jest</em> is based upon <em>Jasmine</em> there’s no need to change the test already present in the scaffolded application.</p>\n<p>The only noticeable difference between <em>Jest</em> and <em>Jasmine</em> are the spies. A spy in Jest by default will be like a <code class=\"language-text\">callThrough</code>, you will need to mock it if you want to emulate Jasmine spies.</p>\n<p>We can now start testing our application and leverage the mocking functionality that Jest provide.</p>\n<h4>Services</h4>\n<p>Services are probably one of the easiest elements to test. In the end they are only ES6 classes and you can ( and you should ) test them directly without using <em>TestBed</em>. The reason why i’m saying this are multiples.</p>\n<p>This code is based upon the new <code class=\"language-text\">HttpClient</code> released with Angular 4.3 which makes things easier also when using <em>TestBed</em>.</p>\n<p>We have the following API:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span>\n  <span class=\"token property\">\"DUB\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Dublin\"</span>\n    ...\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"MAD\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"name\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Madrid\"</span>\n    ...\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  ...\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>And our service needs to retrieve those airports and order them by they code and also to retrieve a single airport. I will use <a href=\"https://ramdajs.com\">ramda</a> to reduce the boilerplate of our code and spice up the code with some functional programming.</p>\n<p>So the first one will be called <code class=\"language-text\">fetchAll$</code></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\">fetchAll$</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Observable<span class=\"token operator\">&lt;</span>any<span class=\"token operator\">></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><span class=\"token string\">'https://foo.bar.com/airports'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span>toPairs<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token function\">sortBy</span><span class=\"token punctuation\">(</span><span class=\"token function\">compose</span><span class=\"token punctuation\">(</span>\n    toLower<span class=\"token punctuation\">,</span>\n    head\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>We are transforming the API first into pairs [key, value] using the <code class=\"language-text\">toPairs</code> function and after we sort all the airports by their codes.</p>\n<p>The second method of our service needs to fetch a single airport instead:</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\">fetchByIATA$</span><span class=\"token punctuation\">(</span>iata<span class=\"token operator\">:</span> string<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Observable<span class=\"token operator\">&lt;</span>any<span class=\"token operator\">|</span><span class=\"token keyword\">undefined</span><span class=\"token operator\">></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><span class=\"token string\">'https://foo.bar.com/airports'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token function\">prop</span><span class=\"token punctuation\">(</span>iata<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><code class=\"language-text\">fetchByIATA$</code> just return the value of the specific key, in this case IATA code, or undefined using <code class=\"language-text\">prop</code> function from ramda.</p>\n<p>This is the whole 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> 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<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> HttpClient <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<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> Observable <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'rxjs'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token string\">'rxjs/add/operator/map'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span>\n  toPairs<span class=\"token punctuation\">,</span>\n  compose<span class=\"token punctuation\">,</span>\n  head<span class=\"token punctuation\">,</span>\n  toLower<span class=\"token punctuation\">,</span>\n  prop<span class=\"token punctuation\">,</span>\n  sortBy\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'ramda'</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\">SampleService</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token keyword\">private</span> http<span class=\"token operator\">:</span> HttpClient</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">public</span> <span class=\"token function\">fetchAll$</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Observable<span class=\"token operator\">&lt;</span>any<span class=\"token operator\">></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><span class=\"token string\">'https://foo.bar.com/airports'</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span>toPairs<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token function\">sortBy</span><span class=\"token punctuation\">(</span><span class=\"token function\">compose</span><span class=\"token punctuation\">(</span>\n      toLower<span class=\"token punctuation\">,</span>\n      head\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><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\">fetchByIATA$</span><span class=\"token punctuation\">(</span>iata<span class=\"token operator\">:</span> string<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Observable<span class=\"token operator\">&lt;</span>any<span class=\"token operator\">|</span><span class=\"token keyword\">undefined</span><span class=\"token operator\">></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><span class=\"token string\">'https://foo.bar.com/airports'</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token function\">prop</span><span class=\"token punctuation\">(</span>iata<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>We need here to mock the http response because we don’t want to hit the server for each test and remember we are doing unit tests not end to end or integration tests.</p>\n<p>With the new <code class=\"language-text\">HttpClient</code> there’s no need to configure <strong><em>mockBackend</em></strong> and this is such a relief.</p>\n<p>First thing we have to configure <em>TestBed</em> to load our service with <em>HttpClientTestingModule</em>, this will give us the ability to intercept and mock our backend calls.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><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> HttpClientTestingModule <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    providers<span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n      SampleService\n    <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>After <em>TestBed</em> is configured we now can get our service to test and a mocking http controller from the injector:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token function\">beforeEach</span><span class=\"token punctuation\">(</span>\n  <span class=\"token function\">inject</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span>SampleService<span class=\"token punctuation\">,</span> HttpTestingController<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">_service<span class=\"token punctuation\">,</span> _httpMock</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    service <span class=\"token operator\">=</span> _service<span class=\"token punctuation\">;</span>\n    httpMock <span class=\"token operator\">=</span> _httpMock<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Now that we have all the setup we can proceed with\nthe single tests</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\">'fetchAll$: should return a sorted list'</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> mockAirports <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>  \n    <span class=\"token constant\">DUB</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> name<span class=\"token operator\">:</span> <span class=\"token string\">'Dublin'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token constant\">WRO</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> name<span class=\"token operator\">:</span> <span class=\"token string\">'Wroclaw'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token constant\">MAD</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> name<span class=\"token operator\">:</span> <span class=\"token string\">'Madrid'</span> <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n  service<span class=\"token punctuation\">.</span><span class=\"token function\">fetchAll$</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\">airports</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>airports<span class=\"token punctuation\">.</span>length<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>airports<span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'WRO'</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 keyword\">const</span> req <span class=\"token operator\">=</span> httpMock<span class=\"token punctuation\">.</span><span class=\"token function\">expectOne</span><span class=\"token punctuation\">(</span><span class=\"token string\">'https://foo.bar.com/airports'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  req<span class=\"token punctuation\">.</span><span class=\"token function\">flush</span><span class=\"token punctuation\">(</span>mockAirports<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  httpMock<span class=\"token punctuation\">.</span><span class=\"token function\">verify</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 new <code class=\"language-text\">HttpClient</code> does actually reminds me of <em>AngularJS</em> v1.x way of testing http calls. We are defining what we are expecting from the function invocation and than through the <code class=\"language-text\">httpMock</code> object we specify what calls we are expecting and what to return <code class=\"language-text\">flush</code>. In the end we call the <code class=\"language-text\">verify()</code> function to make sure that there are no pending connections.</p>\n<p>Here’s the link to the full <a href=\"https://gist.github.com/izifortune/192cf86f7b28b48c56be3d57462185eb\">source code</a></p>\n<p>Using <em>Jest</em> the previous suite will take this time:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/dist/static/53709623361ffe7043a57e98e1d8bcd1/08ee0/service_bed.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 10.135135135135135%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCAACABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAEDBv/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHLUCQD/8QAFBABAAAAAAAAAAAAAAAAAAAAEP/aAAgBAQABBQJ//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAEP/aAAgBAQAGPwJ//8QAFxAAAwEAAAAAAAAAAAAAAAAAARARIf/aAAgBAQABPyE7K//aAAwDAQACAAMAAAAQj/8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAEFAQAAAAAAAAAAAAAAASEAEBExQXH/2gAIAQEAAT8QgUlMq9p2+2//2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"service bed\"\n        title=\"service bed\"\n        src=\"/dist/static/53709623361ffe7043a57e98e1d8bcd1/625aa/service_bed.jpg\"\n        srcset=\"/dist/static/53709623361ffe7043a57e98e1d8bcd1/c4d45/service_bed.jpg 148w,\n/dist/static/53709623361ffe7043a57e98e1d8bcd1/1f0d7/service_bed.jpg 295w,\n/dist/static/53709623361ffe7043a57e98e1d8bcd1/625aa/service_bed.jpg 590w,\n/dist/static/53709623361ffe7043a57e98e1d8bcd1/f8367/service_bed.jpg 885w,\n/dist/static/53709623361ffe7043a57e98e1d8bcd1/fab84/service_bed.jpg 1180w,\n/dist/static/53709623361ffe7043a57e98e1d8bcd1/08ee0/service_bed.jpg 2560w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>Another option that we can explore is to mock directly <code class=\"language-text\">HttpClient</code>, in this example we are only interested in the <code class=\"language-text\">get</code> function which needs to return an observable containing our data.</p>\n<p>We will not use <em>TestBed</em> at all but just use a mock function that <em>Jest</em> provides.</p>\n<p><code class=\"language-text\">SampleService</code> requires <code class=\"language-text\">HttpClient</code> in the constructor:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><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\">SampleService</span><span class=\"token punctuation\">(</span>http<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 will pass our stub to the <em>SampleService</em>, and typescript will complain that there are missing properties for <em>HttpClient</em>. To overcome this we can:</p>\n<p>Use always the <code class=\"language-text\">as any</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><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\">SampleService</span><span class=\"token punctuation\">(</span>http <span class=\"token keyword\">as</span> any<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>If you don’t want to repeat the as any keyword or you can create a small function which will do it for you and then later\non import it:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> provide <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>mock<span class=\"token operator\">:</span> any<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> <span class=\"token parameter\">any</span> <span class=\"token operator\">=></span> mock<span class=\"token punctuation\">;</span>\n<span class=\"token operator\">...</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\">SampleService</span><span class=\"token punctuation\">(</span><span class=\"token function\">provide</span><span class=\"token punctuation\">(</span>http<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>At this point we can specify the test like the following:</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\">'fetchAll$: should return a sorted list'</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  http<span class=\"token punctuation\">.</span>get<span class=\"token punctuation\">.</span><span class=\"token function\">mockImplmentationOnce</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> Observable<span class=\"token punctuation\">.</span><span class=\"token function\">of</span><span class=\"token punctuation\">(</span>mockAirports<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  service<span class=\"token punctuation\">.</span><span class=\"token function\">fetchAll$</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 punctuation\">(</span><span class=\"token parameter\">airports</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>http<span class=\"token punctuation\">.</span>get<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBeCalledWith</span><span class=\"token punctuation\">(</span><span class=\"token string\">'https://foo.bar.com/airports'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>airports<span class=\"token punctuation\">.</span>length<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>airports<span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toBe</span><span class=\"token punctuation\">(</span><span class=\"token string\">'WRO'</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>We are calling <code class=\"language-text\">mockImplementationOnce</code> as the name describes it to mock it just once and return an <em>Observable</em> of our <em>mockAirports</em>, we are repeating the exact same assertion that we did before.</p>\n<p>Here’s the link to the full <a href=\"https://gist.github.com/izifortune/3ac7786a7033cc39eb588d0888ff96c9\">source code</a></p>\n<p>And this is the time of execution:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/dist/static/b0af985419c38395e2b12b58e2548406/08ee0/service_nobed.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 8.783783783783782%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCAACABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAEDBv/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHLUCQD/8QAFBABAAAAAAAAAAAAAAAAAAAAEP/aAAgBAQABBQJ//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAEP/aAAgBAQAGPwJ//8QAFxABAAMAAAAAAAAAAAAAAAAAAQAQMf/aAAgBAQABPyFjtf/aAAwDAQACAAMAAAAQD/8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAFhAAAwAAAAAAAAAAAAAAAAAAABAx/9oACAEBAAE/EBRf/9k='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"service nobed\"\n        title=\"service nobed\"\n        src=\"/dist/static/b0af985419c38395e2b12b58e2548406/625aa/service_nobed.jpg\"\n        srcset=\"/dist/static/b0af985419c38395e2b12b58e2548406/c4d45/service_nobed.jpg 148w,\n/dist/static/b0af985419c38395e2b12b58e2548406/1f0d7/service_nobed.jpg 295w,\n/dist/static/b0af985419c38395e2b12b58e2548406/625aa/service_nobed.jpg 590w,\n/dist/static/b0af985419c38395e2b12b58e2548406/f8367/service_nobed.jpg 885w,\n/dist/static/b0af985419c38395e2b12b58e2548406/fab84/service_nobed.jpg 1180w,\n/dist/static/b0af985419c38395e2b12b58e2548406/08ee0/service_nobed.jpg 2560w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>Let’s recap, a suite running two tests with TestBed is taking <em>99ms</em> in total while without TestBed its only <em>12ms</em>.</p>\n<p>Note that i’ve used already in the second test jest advanced mock functions. I’m requesting directly a mock function through <code class=\"language-text\">jest.fn()</code>, if you want to read more about those mock functions please have a look <a href=\"https://facebook.github.io/jest/docs/en/mock-functions.html#content\">here</a>.</p>\n<h3>Final comparison</h3>\n<p>Now that we have those two extra unit tests let’s try to run another time the two unit tests suite, one with <em>Karma + Chrome</em>, the other with <em>Jest</em> and see the results.</p>\n<p>I’ve create the following script to track out the time on my local machine:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token assign-left variable\">start</span><span class=\"token operator\">=</span><span class=\"token environment constant\">$SECONDS</span>\n<span class=\"token function\">yarn</span> <span class=\"token builtin class-name\">test</span> -- --single-run\n<span class=\"token assign-left variable\">end</span><span class=\"token operator\">=</span><span class=\"token environment constant\">$SECONDS</span>\n\n<span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"duration: <span class=\"token variable\"><span class=\"token variable\">$((</span>SECONDS<span class=\"token operator\">-</span>start<span class=\"token variable\">))</span></span> seconds elapsed..\"</span></code></pre></div>\n<p><strong><em>karma + chrome</em></strong>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/dist/static/fff5d88f6f33069ade6e35426a5af270/08ee0/chrome_complex_first.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.54054054054054%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCAAIABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBv/EABUBAQEAAAAAAAAAAAAAAAAAAAEA/9oADAMBAAIQAxAAAAHKVAgN/8QAFhAAAwAAAAAAAAAAAAAAAAAAABAh/9oACAEBAAEFAiL/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAQ/9oACAEBAAY/An//xAAYEAADAQEAAAAAAAAAAAAAAAAAARFBcf/aAAgBAQABPyFzTgiP/9oADAMBAAIAAwAAABCP3//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABURAQEAAAAAAAAAAAAAAAAAAAEQ/9oACAECAQE/ECf/xAAZEAEAAwEBAAAAAAAAAAAAAAABABFBgcH/2gAIAQEAAT8QuLI9lIxHHyf/2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"chrome complex first\"\n        title=\"chrome complex first\"\n        src=\"/dist/static/fff5d88f6f33069ade6e35426a5af270/625aa/chrome_complex_first.jpg\"\n        srcset=\"/dist/static/fff5d88f6f33069ade6e35426a5af270/c4d45/chrome_complex_first.jpg 148w,\n/dist/static/fff5d88f6f33069ade6e35426a5af270/1f0d7/chrome_complex_first.jpg 295w,\n/dist/static/fff5d88f6f33069ade6e35426a5af270/625aa/chrome_complex_first.jpg 590w,\n/dist/static/fff5d88f6f33069ade6e35426a5af270/f8367/chrome_complex_first.jpg 885w,\n/dist/static/fff5d88f6f33069ade6e35426a5af270/fab84/chrome_complex_first.jpg 1180w,\n/dist/static/fff5d88f6f33069ade6e35426a5af270/08ee0/chrome_complex_first.jpg 2560w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/dist/static/d26fd1a96bf23f938893e88a1f885dd2/08ee0/chrome_complex_last.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 37.83783783783784%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCAAIABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAMG/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAclMQD//xAAWEAADAAAAAAAAAAAAAAAAAAABEBH/2gAIAQEAAQUCMf8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAEP/aAAgBAQAGPwJ//8QAFhABAQEAAAAAAAAAAAAAAAAAARBB/9oACAEBAAE/IWsv/9oADAMBAAIAAwAAABD/AP8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAFxABAAMAAAAAAAAAAAAAAAAAARAxUf/aAAgBAQABPxBho7P/2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"chrome complex last\"\n        title=\"chrome complex last\"\n        src=\"/dist/static/d26fd1a96bf23f938893e88a1f885dd2/625aa/chrome_complex_last.jpg\"\n        srcset=\"/dist/static/d26fd1a96bf23f938893e88a1f885dd2/c4d45/chrome_complex_last.jpg 148w,\n/dist/static/d26fd1a96bf23f938893e88a1f885dd2/1f0d7/chrome_complex_last.jpg 295w,\n/dist/static/d26fd1a96bf23f938893e88a1f885dd2/625aa/chrome_complex_last.jpg 590w,\n/dist/static/d26fd1a96bf23f938893e88a1f885dd2/f8367/chrome_complex_last.jpg 885w,\n/dist/static/d26fd1a96bf23f938893e88a1f885dd2/fab84/chrome_complex_last.jpg 1180w,\n/dist/static/d26fd1a96bf23f938893e88a1f885dd2/08ee0/chrome_complex_last.jpg 2560w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>I’ve added the karma-verbose-reporter to get more informations about the tests and the total results is <strong><em>22s</em></strong>.</p>\n<p>For <em>Jest</em> the script to track time instead is the following:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token assign-left variable\">start</span><span class=\"token operator\">=</span><span class=\"token environment constant\">$SECONDS</span>\n<span class=\"token function\">yarn</span> <span class=\"token builtin class-name\">test</span> -- --verbose\n<span class=\"token assign-left variable\">end</span><span class=\"token operator\">=</span><span class=\"token environment constant\">$SECONDS</span>\n\n<span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"duration: <span class=\"token variable\"><span class=\"token variable\">$((</span>SECONDS<span class=\"token operator\">-</span>start<span class=\"token variable\">))</span></span> seconds elapsed..\"</span></code></pre></div>\n<p><code class=\"language-text\">--verbose</code> option will track the execution of each test inside the suite.</p>\n<p><strong><em>jest</em></strong>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/dist/static/4d6012efcea5897593c562914af9cb8d/08ee0/time_jest.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCAAKABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIDBv/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHlcLhAP//EABYQAQEBAAAAAAAAAAAAAAAAABABAv/aAAgBAQABBQKun//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABgQAAIDAAAAAAAAAAAAAAAAAAEQETFR/9oACAEBAAE/IYnHZ//aAAwDAQACAAMAAAAQf/8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAFxABAQEBAAAAAAAAAAAAAAAAAREgMf/aAAgBAQABPxAotF4yaP/Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"time jest\"\n        title=\"time jest\"\n        src=\"/dist/static/4d6012efcea5897593c562914af9cb8d/625aa/time_jest.jpg\"\n        srcset=\"/dist/static/4d6012efcea5897593c562914af9cb8d/c4d45/time_jest.jpg 148w,\n/dist/static/4d6012efcea5897593c562914af9cb8d/1f0d7/time_jest.jpg 295w,\n/dist/static/4d6012efcea5897593c562914af9cb8d/625aa/time_jest.jpg 590w,\n/dist/static/4d6012efcea5897593c562914af9cb8d/f8367/time_jest.jpg 885w,\n/dist/static/4d6012efcea5897593c562914af9cb8d/fab84/time_jest.jpg 1180w,\n/dist/static/4d6012efcea5897593c562914af9cb8d/08ee0/time_jest.jpg 2560w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>Jest is still leading with only <strong><em>5s</em></strong> execution.</p>\n<h3>Bonus</h3>\n<p>I mentioned before the instant feedback, <em>Jest</em> will automatically run the tests related to the file that you modified. This is especially good while watching.</p>\n<p>If we commit the changes to our repository and try to modify only <code class=\"language-text\">app.component.ts</code> while running <code class=\"language-text\">yarn test:watch</code> you will notice that only the <code class=\"language-text\">app.component.spec.ts</code> is running:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 590px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/dist/static/d36141fd173bfda918f3336bd1e82444/08ee0/instant_feedback.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 54.05405405405405%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAECBQb/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAP/2gAMAwEAAhADEAAAAci2RAsTF//EABsQAAEEAwAAAAAAAAAAAAAAAAEAAhESAyIx/9oACAEBAAEFAirGLEI8jVuJhb//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAXEQEAAwAAAAAAAAAAAAAAAAAAAQID/9oACAECAQE/AU61f//EABkQAAIDAQAAAAAAAAAAAAAAAAABEBEhMf/aAAgBAQAGPwIo64QsP//EABsQAQADAAMBAAAAAAAAAAAAAAEAESFBUWFx/9oACAEBAAE/IV7MqVDhYYgvjBFLK2ohu07n/9oADAMBAAIAAwAAABAHD//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAwEBPxBtf//EABYRAQEBAAAAAAAAAAAAAAAAAAEAEf/aAAgBAgEBPxByGol//8QAHBABAAICAwEAAAAAAAAAAAAAAQARITFBYYGR/9oACAEBAAE/EFTLzvuK6rSUPIRSd0oQjDgI84LLfbCqoVbZfs//2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"instant feedback\"\n        title=\"instant feedback\"\n        src=\"/dist/static/d36141fd173bfda918f3336bd1e82444/625aa/instant_feedback.jpg\"\n        srcset=\"/dist/static/d36141fd173bfda918f3336bd1e82444/c4d45/instant_feedback.jpg 148w,\n/dist/static/d36141fd173bfda918f3336bd1e82444/1f0d7/instant_feedback.jpg 295w,\n/dist/static/d36141fd173bfda918f3336bd1e82444/625aa/instant_feedback.jpg 590w,\n/dist/static/d36141fd173bfda918f3336bd1e82444/f8367/instant_feedback.jpg 885w,\n/dist/static/d36141fd173bfda918f3336bd1e82444/fab84/instant_feedback.jpg 1180w,\n/dist/static/d36141fd173bfda918f3336bd1e82444/08ee0/instant_feedback.jpg 2560w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<h3>Conclusion</h3>\n<p>I do believe that the frameworks should encourage testing and a crucial point is their speed. <em>Jest</em> provides all of this and we’ve already switched in Ryanair from karma + chrome to <em>Jest</em>.</p>\n<p>PS: If you care about unit tests and Angular we are hiring at Ryanair, <a href=\"https://careers.ryanair.com/search/#search/page=1search/?departments=itlabs&#x26;departments=itlabs\">Join us</a>.</p>","frontmatter":{"title":"Unit testing Angular applications with Jest","date":"July 26, 2017","description":null,"socialImage":{"childImageSharp":{"fixed":{"src":"/dist/static/4d8300882bb751f40a76b7e5de59cea2/048fd/jest-angular-3.png"}}},"image":{"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsSAAALEgHS3X78AAAA50lEQVQY02PQLT+OhrQrTjhlbqm3b1wn4Nmsme4TvkgPQw0EMSBz9MuOqdacq3Jqvctg8IJF/7Fp5HWjkItKnlNlw3WqThHUfFS57kKbTfVLBpXbfLYPoiqvZ7Zd0fBdIuiuXX2akObSo0r1F7M8+l4J2rxIanxZPeVB29zrBsE9irEatef0yo4R0KzccDHab/obdd+XpRPvuqSfc8++bRzSoJOp2nAJ6C58moFma1SfcUrZeEox6LNF1D39sAvSjicYtBL8JqvWniegGaJfq/KUVfbOfvOy42yWU2TCvBJXAUUw3QxEAF+Uwh+3uqwzAAAAAElFTkSuQmCC","aspectRatio":2.737704918032787,"src":"/dist/static/b2739a3befdcefe030483fe5722855e2/a5924/jest-angular-4.png","srcSet":"/dist/static/b2739a3befdcefe030483fe5722855e2/17cc0/jest-angular-4.png 167w,\n/dist/static/b2739a3befdcefe030483fe5722855e2/f7869/jest-angular-4.png 333w,\n/dist/static/b2739a3befdcefe030483fe5722855e2/a5924/jest-angular-4.png 666w,\n/dist/static/b2739a3befdcefe030483fe5722855e2/605d2/jest-angular-4.png 671w","sizes":"(max-width: 666px) 100vw, 666px"}}}}}},"pageContext":{"slug":"/unit-testing-angular-applications-with-jest/","previous":{"fields":{"slug":"/demystifying-functional-programming-with-ramda/"},"frontmatter":{"title":"Demystifying functional programming with Ramda"}},"next":{"fields":{"slug":"/managing-modules-with-angular/"},"frontmatter":{"title":"Managing modules with Angular"}}}}}