<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Artem Zakharchenko</title>
    <description>The latest articles on DEV Community by Artem Zakharchenko (@kettanaito).</description>
    <link>https://dev.to/kettanaito</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F269316%2F29f14783-3c70-4056-9661-46f35c3fcf09.jpg</url>
      <title>DEV Community: Artem Zakharchenko</title>
      <link>https://dev.to/kettanaito</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kettanaito"/>
    <language>en</language>
    <item>
      <title>Mock Service Worker adopts a brand-new request interception algorithm for Node.js.</title>
      <dc:creator>Artem Zakharchenko</dc:creator>
      <pubDate>Mon, 21 Feb 2022 11:02:06 +0000</pubDate>
      <link>https://dev.to/kettanaito/mock-service-worker-adopts-a-brand-new-request-interception-algorithm-for-nodejs-3hj9</link>
      <guid>https://dev.to/kettanaito/mock-service-worker-adopts-a-brand-new-request-interception-algorithm-for-nodejs-3hj9</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;One of the most prominent features of &lt;a href="https://mswjs.io" rel="noopener noreferrer"&gt;Mock Service Worker&lt;/a&gt; has always been the way it establishes the boundaries between what is mocked and what is not. Conventional API mocking solutions turn any fetch or axios call into a black hole through the substitution of the entire client with a mocked re-implementation. In contrast, MSW brings Service Workers to the table, which allows request clients to execute in their entirety, bringing more confidence to your tests and prototypes. The reason why it increases confidence is simple—your system underneath your test resembles your actual production system. Allow me to elaborate with a quick example.&lt;/p&gt;

&lt;p&gt;Imagine you are writing an abstract test for a bank branch—one with a physical location where people come to open accounts, withdraw funds, and deposit their earnings and investments. Let's say you want to test that your bank can handle deposits. You model a situation where a customer walks in, goes to the cash stand, and hands their money to the teller. The teller then puts the deposit into the bank system, which updates the customer's account balance.&lt;/p&gt;

&lt;p&gt;Since this is a test of an interaction, spending actual money to put into accounts isn't the best idea (what an expensive test that would be! 😉). Instead, you decide to mock certain parts of your bank during the test, so they don't &lt;em&gt;actually&lt;/em&gt; happen.. You do remember, however, that the point of any test is still to &lt;em&gt;test a system or its part&lt;/em&gt;, so you ought to introduce mocking carefully, understanding which parts of the "customer → bank" interactions can be replaced without sacrificing the actual functionality you wish to test—that your bank can handle deposits.&lt;/p&gt;

&lt;p&gt;Ideally, it's only that last "cashier → bank system" procedure you should mock. The cashier would receive fake money (mocked), and interact with the bank systems that are already pre-configured (mocked) to respond with a "Okay, we've got the funds!" state. Walking into the bank, finding the cash stand, and speaking to a cashier are all crucial aspects for our customer which should remain authentic and real.&lt;/p&gt;

&lt;p&gt;At this point, it should be clear I'm hinting at the HTTP communication with this story, where the customer is a request, and the bank is your request client that processes it. The final part—the "cashier → bank system"—is where you should employ API mocking.. So let's see what happens when you bring a common API mocking library to do the job.&lt;/p&gt;

&lt;p&gt;Due to the implementation details of such libraries, what happens is that you end up with &lt;em&gt;your entire bank being replaced&lt;/em&gt;. Yes, not just the cashier or a cash stand, &lt;em&gt;the entire bank&lt;/em&gt;. Because a conventional interception of request can be roughly represented as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// node_modules/api-mocking-library/index.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mockRequestClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mockRequestClient&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For many tools, the lowest level of operation becomes the request client. In other words, they replace &lt;code&gt;window.fetch&lt;/code&gt;, &lt;code&gt;axios&lt;/code&gt;, &lt;code&gt;react-query&lt;/code&gt; and other clients during your tests, so your code no longer executes them. Basically, your customer no longer walks into your actual bank. Instead, they walk into a fake building, constructed to look and resemble the bank. Since the scope of the mock has grown from a single interaction to the entire building, the surface area where potential issues can happen increases drastically.&lt;/p&gt;

&lt;p&gt;This is precisely where Mock Service Worker introduces interception of requests via the Service Worker API. This allows you to keep the bank, the cash stand, and the cashier as real as they are in production. Oh, but there's more! Even the "cashier → bank system" communication becomes real because the worker would intercept the deposit request &lt;em&gt;after it's left the bank&lt;/em&gt;. This keeps the mocked surface to a ridiculous minimum. &lt;/p&gt;

&lt;p&gt;This has been our algorithm to intercept requests that occur in a browser for years now. Unfortunately, this hasn't been the case for Node.js.&lt;/p&gt;


&lt;h2&gt;
  
  
  Request interception in Node.js
&lt;/h2&gt;

&lt;p&gt;Node.js is an entirely different environment and, as one would expect, it has its own rules and limitations. It's like an alternative universe where you can still have your bank, but all its doors are now made of blue wood, and all the communication is conducted via woolen envelopes... that's just how banks work in this world.&lt;/p&gt;

&lt;p&gt;There's simply no intermediate network layer like Service Workers in Node.js. Once requests happen, they happen, and nothing can intercept them past that point. This design choice is why request clients become the lowest point of interception available in a Node.js environment.&lt;/p&gt;

&lt;p&gt;Due to this limitation, request interception in Node.js is implemented by stubbing request modules:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// node_modules/api-mocking-library/index.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// My custom function replaces the "bank"&lt;/span&gt;
&lt;span class="c1"&gt;// (the "https" module) and becomes responsible&lt;/span&gt;
&lt;span class="c1"&gt;// for handling any issued requests.&lt;/span&gt;
&lt;span class="nx"&gt;https&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Modules in Node.js share the same scope, so modifying a standard API like &lt;code&gt;https&lt;/code&gt; in one module will affect its references in all other modules.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Module stubbing is a reasonable strategy within the circumstances, and that is also how MSW intercepts requests in Node.js.&lt;/p&gt;

&lt;p&gt;Or rather, how it used to, until we tried something... unusual.&lt;/p&gt;


&lt;h2&gt;
  
  
  Brand-new interception algorithm
&lt;/h2&gt;

&lt;p&gt;Starting from the latest version of Mock Service Worker (&lt;a href="https://github.com/mswjs/msw/releases/tag/v0.38.0" rel="noopener noreferrer"&gt;&lt;code&gt;0.38.0&lt;/code&gt;&lt;/a&gt;), the library will employ a request interception algorithm that has been rewritten from the ground-up. There's no more module stubbing, no more replacing the entire bank. Instead, we are introducing a way to extend the request modules, allowing them to execute in their entirety and intercept the outgoing requests at the last possible moment (wait, we've heard this somewhere, haven't we?).&lt;/p&gt;

&lt;p&gt;We achieve this through &lt;em&gt;module extension&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Technically, both &lt;code&gt;http&lt;/code&gt; and &lt;code&gt;https&lt;/code&gt; modules are just wrappers around the &lt;code&gt;ClientRequest&lt;/code&gt; class. &lt;em&gt;That&lt;/em&gt; is actually the request that is being constructed and sent to a server. That is also a lower surface where we could move our logic in order to be even closer to the constructed requests.&lt;/p&gt;

&lt;p&gt;Still, we do not wish to tread same water by hijacking the &lt;code&gt;ClientRequest&lt;/code&gt; class and forcing it to do our bidding:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Both "http" and "https" use the same "http.ClientRequest"&lt;/span&gt;
&lt;span class="c1"&gt;// configured accordingly for HTTP and HTTPS&lt;/span&gt;
&lt;span class="c1"&gt;// connections.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ClientRequest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// That is NOT what we want!&lt;/span&gt;
&lt;span class="nx"&gt;ClientRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClientRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Now, suddenly, resolve with a mocked response!&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Unfortunately, this is no different than stubbing &lt;code&gt;http&lt;/code&gt;/&lt;code&gt;https&lt;/code&gt; modules directly.&lt;/p&gt;

&lt;p&gt;What we've decided to do is to extend the &lt;code&gt;ClientRequest&lt;/code&gt; class, effectively creating a child class that is much like its parent, albeit with a few deviations.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NodeClientRequest&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ClientRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Respond with a mocked response.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This may look similar at first, but, there is a fundamental difference between the choice of &lt;em&gt;replacing&lt;/em&gt; or &lt;em&gt;extending&lt;/em&gt; the &lt;code&gt;ClientRequest&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;When you replace that class, you're removing it from existence, swapping it with a seemingly compatible class that you've written by yourself. This means &lt;em&gt;you&lt;/em&gt; (the API mocking library in this context) become responsible for respecting and handling all the internals of that class. And those are many: establishing the socket connection, writing request/response body, handling headers, etc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In our previous implementation, that's exactly what we were doing, handling all those moving parts by ourselves.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But what happens when you extend the class is an entirely different story. &lt;/p&gt;

&lt;p&gt;Class extension &lt;em&gt;preserves&lt;/em&gt; the behavior of the parent class, producing a child class that &lt;em&gt;augments it&lt;/em&gt;. So, while we were previously forced to re-implement the response handling logic just to be able to intercept an original response, we can now hook into the &lt;code&gt;ClientRequest.prototype.end&lt;/code&gt; method and simply use &lt;code&gt;super()&lt;/code&gt; whenever we need to bypass a request.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NodeRequestClient&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ClientRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockedResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockedResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Calling "super.end()" will perform the intercepted request&lt;/span&gt;
    &lt;span class="c1"&gt;// in the identical way it's perform without mocks.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The ability to execute the parent class' logic through &lt;code&gt;super()&lt;/code&gt; is what allows us to keep the default behavior of request modules intact. We just call out to it whenever it's needed!&lt;/p&gt;

&lt;p&gt;It's been a rather challenging implementation, as allowing &lt;code&gt;ClientRequest&lt;/code&gt; to execute normally imposes a certain behavior difference when constructing requests. &lt;/p&gt;

&lt;p&gt;Let's look at one of these challenges that we've faced during this rewrite.&lt;/p&gt;
&lt;h2&gt;
  
  
  Handling refused connections
&lt;/h2&gt;

&lt;p&gt;Extending the ClientRequest class means that all requests begin to establish actual HTTP connection. This quickly becomes problematic. When you're prototyping against a non-existing endpoint in Node.js, such connections would be refused! In addition, when you're testing the code that hits actual production servers, connecting to those is not what you want your tests to do.&lt;/p&gt;

&lt;p&gt;Presently, we've landed on the decision to &lt;em&gt;always establish the connection&lt;/em&gt;, no matter if the request is supposed to be mocked or not.&lt;/p&gt;

&lt;p&gt;While this sounds unconventional, the cost of establishing an actual socket connection is rather small. Note that we are still preventing any data from being sent or received through that connection. You can think of it as a &lt;code&gt;HEAD&lt;/code&gt; request to your endpoint.&lt;/p&gt;

&lt;p&gt;What about the scenarios when the connection fails? What about requesting non-existing endpoints?&lt;/p&gt;

&lt;p&gt;It comes down to proper error handling in &lt;code&gt;ClientRequest&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The connection itself happens right away, while first constructing the request instance. At that time, it's impossible for the library to know if there's a request handler created to intercept this particular request. However, it's not too early to handle connection errors.&lt;/p&gt;

&lt;p&gt;So what ends up happening is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Request instance attempts to connect to the server;&lt;/li&gt;
&lt;li&gt;This connection is either established (the server exists) or refused (the server does not exist or couldn't otherwise establish the connection). In either case, &lt;em&gt;no data is being transferred yet&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;If the connection is refused, MSW catches the respective error and &lt;em&gt;silences it&lt;/em&gt; until it knows there are no matching request handlers. Once this is known, the library &lt;em&gt;replays the errors&lt;/em&gt;, propagating it to the process. &lt;/li&gt;
&lt;li&gt;If the connection is established, MSW prevents any data from being written or received until it's certain there are no matching request handlers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We are convinced that keeping the connection logic is crucial to maintain the integrity of the &lt;code&gt;ClientRequest&lt;/code&gt; instances. This does not mean that you must request actual endpoints from now on, or even that you must be connected to the internet while testing. It only means that request instances execute more of its internal logic, including the logic that's responsible for establishing the connection.&lt;/p&gt;


&lt;h2&gt;
  
  
  What should I expect as MSW user?
&lt;/h2&gt;

&lt;p&gt;Expect to update &lt;code&gt;msw&lt;/code&gt; in your projects!&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;msw@latest &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn add msw@latest &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The new algorithm is an internal change, so there are no breaking changes to the public API or behaviors of MSW in Node.js. &lt;/p&gt;

&lt;p&gt;That being said, this is quite a shift from our previous implementation, so we expect issues to be reported occasionally. We highly encourage you to do so whenever you encounter an unexpected behavior or a regression in your Node.js tests! &lt;a href="https://github.com/mswjs/interceptors/issues/new" rel="noopener noreferrer"&gt;Submit an issue here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our motivation behind this change is to reduce the mocked surface in Node.js, bringing you a similar level of confidence that you get when using MSW in a browser. &lt;/p&gt;


&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;I hope you're as excited about these changes as I am! There's a long road for us ahead, but it's a road we wish to spend on making your developer experience not just better, but unmatched. We've got a history of using unconventional approaches to API mocking in the browser, and we're thrilled to expand our vision to Node.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/ApiMocking" rel="noopener noreferrer"&gt;Follow MSW on Twitter&lt;/a&gt; to stay updated on the awesome features we're working on! &lt;/p&gt;

&lt;p&gt;Make sure to check out the &lt;code&gt;@mswjs/interceptors&lt;/code&gt;—the low-level interception library that powers Node.js support in MSW:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mswjs" rel="noopener noreferrer"&gt;
        mswjs
      &lt;/a&gt; / &lt;a href="https://github.com/mswjs/interceptors" rel="noopener noreferrer"&gt;
        interceptors
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Low-level network interception library.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@mswjs/interceptors" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/76a18f31543b82214da048bb447c69d9a46adbb4356ee0ebb31ca989fa7fa75f/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f406d73776a732f696e746572636570746f72732e737667" alt="Latest version"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;&lt;code&gt;@mswjs/interceptors&lt;/code&gt;&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Low-level network interception library.&lt;/p&gt;

&lt;p&gt;This library supports intercepting the following protocols:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP (via the &lt;code&gt;http&lt;/code&gt; module, &lt;code&gt;XMLHttpRequest&lt;/code&gt;, or &lt;code&gt;globalThis.fetch&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mswjs/interceptors#websocket-interception" rel="noopener noreferrer"&gt;WebSocket&lt;/a&gt; (the &lt;code&gt;WebSocket&lt;/code&gt; class in Undici and in the browser).&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Motivation&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;While there are a lot of network mocking libraries, they tend to use request interception as an implementation detail, giving you a high-level API that includes request matching, timeouts, recording, and so forth.&lt;/p&gt;

&lt;p&gt;This library is a barebones implementation that provides as little abstraction as possible to execute arbitrary logic upon any request. It's primarily designed as an underlying component for high-level API mocking solutions such as &lt;a href="https://github.com/mswjs/msw" rel="noopener noreferrer"&gt;Mock Service Worker&lt;/a&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;How is this library different?&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;A traditional API mocking implementation in Node.js looks roughly like this:&lt;/p&gt;

&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;http&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'node:http'&lt;/span&gt;
&lt;span class="pl-c"&gt;// Store the original request function.&lt;/span&gt;
&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;originalHttpRequest&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;http&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;request&lt;/span&gt;

&lt;span class="pl-c"&gt;// Override the request function entirely.&lt;/span&gt;
&lt;span class="pl-s1"&gt;http&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;request&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;function&lt;/span&gt; &lt;span class="pl-kos"&gt;(&lt;/span&gt;...&lt;span class="pl-s1"&gt;args&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mswjs/interceptors" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>api</category>
      <category>opensource</category>
    </item>
    <item>
      <title>One Thing That May Ruin The New God of War Game</title>
      <dc:creator>Artem Zakharchenko</dc:creator>
      <pubDate>Sat, 11 Sep 2021 23:05:45 +0000</pubDate>
      <link>https://dev.to/kettanaito/one-thing-that-may-ruin-the-new-god-of-war-game-1k0n</link>
      <guid>https://dev.to/kettanaito/one-thing-that-may-ruin-the-new-god-of-war-game-1k0n</guid>
      <description>&lt;p&gt;With the &lt;a href="https://www.youtube.com/watch?v=T5VtfD2i3rc" rel="noopener noreferrer"&gt;PlayStation Showcase 2021&lt;/a&gt; behind our backs, I, just as many others, was excited to finally get the first look at the new God of War titled "Ragnarök". At the next day after watching the showcase a strange feeling settled in my heart. A feeling that the new beloved title may be disastrous. &lt;/p&gt;

&lt;p&gt;To understand my worries, first you need to understand my biggest critique of the previous God of War game, which was widely praised and well-perceived by both critics and gamers. Looking back at it, I couldn't help but notice how a single element of the game introduces so many flaws into otherwise great action experience. That element is RPG.&lt;/p&gt;

&lt;p&gt;Adopting parts of RPG mechanics has become widely popular in action titles in the recent years. From dressing up your assassins in the Victorian era to deciding which perk Geralt of Rivia should level up before going on his next hunt—elements of RPG gameplay has soaked into other genres in many shapes and forms. Needless to say, sometimes this conjunction is far from perfect. In some cases, it straight ruins the game, being a burden rather than an engaging and captivating elements of the gameplay.&lt;/p&gt;

&lt;p&gt;The latest God of War game featured prominent RPG elements like character armor and weapons, and also the skill tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpboawb24j420gzjg4d3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpboawb24j420gzjg4d3.jpg" alt="A skill tree in the God of War" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A skill tree in the God of War (&lt;a href="https://www.youtube.com/watch?v=Dpj9PiIkIQ4" rel="noopener noreferrer"&gt;Source&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am convinced that these elements ruin the game and, moreover, don't belong in action titles in the first place. A strong statement, I know, but let's dig a little bit deeper to see what exactly these RPG elements mean for the game.&lt;/p&gt;

&lt;h2&gt;
  
  
  RPG in action games
&lt;/h2&gt;

&lt;p&gt;RPG is an incredibly popular genre with dozens of renowned titles, gigantic fanbase and stylistic variability. Perhaps the biggest thing that makes this genre stand out is subtly placed right in its name—&lt;em&gt;R&lt;/em&gt; (role). The ability to role-play, meaning playing your character in a role &lt;em&gt;you&lt;/em&gt; see fit, brings an incredible sense of wonder and personalization. &lt;/p&gt;

&lt;p&gt;The thing that makes action games unique is in the genre name as well. It's action. Intricate, thrilling fighting scenes, blood-chilling dialogues and character interactions, and just a bit of sprinkle of epic on top. Action games are known to be huge, vibrant, and flamboyant. Such degree of excitement is usually achieved by pre-defined, mostly linear storytelling, masterfully written and orchestrated like in a big blockbuster movie. While this allows game designers to balance between the unstoppable epic and the intermissions of peace, it takes away any room for variability, any room for &lt;em&gt;role&lt;/em&gt;. Try to remember an action game where your decisions influenced something, or a game where you even had to make any decisions. Most of the times playing such games would feel like watching an interactive movie (and it's great) rather than crafting a unique novel-like story using your character as an ink pen.&lt;/p&gt;

&lt;p&gt;Needless to say that RPG games have dominated the online world with thousands of MMORPG titles. They did and continue doing so due to the addictive gameplay and nearly infinite character progression in a definitely infinite (and often absent) story. No wonder that the action genre tends to borrow such addictive gameplay elements to create a sense of character progression in otherwise progression-less genre.&lt;/p&gt;

&lt;p&gt;I think the main reason to add RPG elements into an action game is to compensate for a short and uninteresting gameplay loop. What can be better than taking a bunch of weapons, armor, perks, all color-graded into perfection, so that the player spends a few more hours in a game that already offered everything it could in the first hour of playing?&lt;/p&gt;

&lt;p&gt;More often than not, RPG elements in action games simply fail and feel out of place, dragging the gameplay away rather than complimenting it. I think that happens because those RPG elements are designed to come hand-in-hand with role playing, which is absent in action games. Moreover, such incompatibility often births a &lt;a href="https://en.wikipedia.org/wiki/Ludonarrative_dissonance" rel="noopener noreferrer"&gt;ludonarrative dissonance&lt;/a&gt;, ruining the immersion that any game strives to create.&lt;/p&gt;

&lt;p&gt;Let me give you an example. Imagine that during one of your world-wondering sessions, your abstract Geralt had stumbled upon an ancient chest. You opened it and found an incredible set of armor, perhaps the best in the game. You feel joy as the next shiny thing lands in your character's inventory. Time passes and you, eventually, reach the next "story" moment—a cutscene. You stare at the polygons on your monitor as they, suddenly, grab your Geralt and throw it against the wall, rendering him half-dead. &lt;em&gt;Wait, what?&lt;/em&gt; you exclaim. Not a single living soul in the game could've beaten you while you wear that armor set. But the cutscene does beat you. Because the cutscene is destined to happen. You accept this as a game detail and head on to find yet another chest with jaw-dropping items that change your gameplay upside-down but have zero effect on the story you're trying to play.&lt;/p&gt;

&lt;p&gt;Now, let's talk about God of War (finally).&lt;/p&gt;

&lt;h2&gt;
  
  
  Role in God of War
&lt;/h2&gt;

&lt;p&gt;When you purchase God of War you're likely expecting to play as a god-crashing brute named Kratos. Although the latest title has opened him up from a rather unconventional (yet great) sensitive side, you'd still be right to expect an occasional ass whipping here and there, using the might of the God of War. In other words, you expect a certain &lt;em&gt;gameplay&lt;/em&gt; based on the game setting and characters. I don't think anybody has tried playing a stealthy Kratos. Partially, because it's against the already written character. Mainly, because the game won't allow you to. Don't be deceived, there is no role in God of War, as you've taken the role of Kratos from the moment you downloaded the game. &lt;/p&gt;

&lt;p&gt;As I've said before, taking on a pre-defined role is an inevitable pre-requisite of a good action adventure game. As I've also stated before, adding RPG elements to a role-less game is a terrible, pointless idea, which is likely there to mask the lack of gameplay than anything else. That's exactly what happens with God of War.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdo0ssffomt3bt9z7qlfg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdo0ssffomt3bt9z7qlfg.jpg" alt="Kratos fighting some enemies" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Source: &lt;a href="https://www.vortex.cz/recenze-god-of-war/" rel="noopener noreferrer"&gt;Vortex&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I challenge you: take a clip of Kratos fighting enemies at the beginning of the game and put it side-by-side with him fighting enemies at the end of the game. You'll be amazed how both fights are, well, identical. The enemy colors and skins may change, but there are still about 3 enemy types in the game. Kratos' may shove off with a few new moves but they hardly have any significant impact on the battle, adding mainly in choreography and style than making an actual gameplay difference. Turns out all those chests and items were there only to fake you feeling engaged, when in actuality Kratos was moving from point A to point B as the story foretells, regardless of your actions. RPG elements were now complimenting the game, they were saving you from feeling bored.&lt;/p&gt;

&lt;h2&gt;
  
  
  The strong side
&lt;/h2&gt;

&lt;p&gt;For a moment, let's imagine God of War without chests, weapons, armors, skills. We will still be left with a bunch of gaming aspects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Combat;&lt;/li&gt;
&lt;li&gt;World exploration;&lt;/li&gt;
&lt;li&gt;Story.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think most of the praise that God of War received was related to its story and, specifically, to &lt;em&gt;how&lt;/em&gt; it was told.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmabf5x3ljh4omhm3mzaj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmabf5x3ljh4omhm3mzaj.jpg" alt="Kratos and Atreas" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Source: &lt;a href="https://www.digitalspy.com/tech/a36637358/god-of-war-sequel-delay-ps4-release/" rel="noopener noreferrer"&gt;DigitalSpy&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The plot itself is a classic travelogue with close to no things to surprise you. The main strength of the story, and also the main thing that the developer team did incredibly well, was the character development during that story.&lt;/p&gt;

&lt;p&gt;Once the item grind is gone, the combat and exploration have almost nothing else to offer. Enemy types are extremely scarce, while the world is, although vast, feels and de-facto is a classic action game world. These two aspects of the game are weak and no amount of armor or skills can make them better. That'd only mask the problem, not solve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to solve it
&lt;/h2&gt;

&lt;p&gt;The biggest mistake I think the developer did was betting too much on the RPG elements in the game. I understand they were supposed to engage the players and gift them the sense of progression, but they do the opposite, dissolving the gameplay with the needless search for gear (that Kratos has no use for story-wise), living in the limbo of the same chest opening animation.&lt;/p&gt;

&lt;p&gt;Instead, they should've focused on what makes an action game stunning: &lt;em&gt;progression through story, not gameplay&lt;/em&gt;. Instead of giving me a new armor in a box, let Kratos tear that armor off an important boss, and do so by &lt;em&gt;his&lt;/em&gt; intentions, not mine (player's). Instead of letting me press a mindless "+" next to a skill, let an encounter with an NPC teach Kratos that skill, making me feel like a journey that the protagonist undertook to learn it as opposed to a new way to swing an axe magically appearing in the hero's memory.&lt;/p&gt;

&lt;p&gt;And I believe the team understands that. The appearance of his twin blades in the second part of the game was phenomenal. Yes, they did extend your combat capabilities, but I'm referring to how their reveal was handled. Kratos retrieved them from his hideout because it was a logical move in the circumstances that the story dictated. Pre-defined story, pre-defined Kratos, pre-defined blades. And it still worked wonderfully because action elements will always work in action games.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F320shge0pt9ipmhf32pc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F320shge0pt9ipmhf32pc.jpg" alt="Thor appearing in the next God of War" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Source: &lt;a href="https://screenrant.com/god-war-ragnarok-trailer-thor-hammer-villain-enemy/" rel="noopener noreferrer"&gt;ScreenRant&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I hope that the next God of War advances the combat and the world, leaving the RPG elements aside, if not abandoning them altogether. I don't need to feel variability from gear in a game where I don't expect variability. I honestly hope that they spend the budget they could allocate on improving weapons and skills on extending the world, crafting more cinematic moments, and, for God's sake, finally adding some nordic Gods to interact with.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>playstation</category>
    </item>
    <item>
      <title>Spawn an HTTP server from your Mock Service Worker request handlers.</title>
      <dc:creator>Artem Zakharchenko</dc:creator>
      <pubDate>Fri, 23 Jul 2021 15:50:15 +0000</pubDate>
      <link>https://dev.to/kettanaito/spawn-an-http-server-from-your-mock-service-worker-request-handlers-2c19</link>
      <guid>https://dev.to/kettanaito/spawn-an-http-server-from-your-mock-service-worker-request-handlers-2c19</guid>
      <description>&lt;p&gt;When &lt;a href="https://mswjs.io/" rel="noopener noreferrer"&gt;Mock Service Worker&lt;/a&gt; was released, it had a clear mission to enable API mocking without the need to spawn and maintain an actual HTTP server. This purposeful restriction, among a few other core principles, has led to thousands of developers writing declarative, agnostic, and reusable mocks every day, prototyping amazing applications and delivering stunning products with confidence.&lt;/p&gt;

&lt;p&gt;While our "you don't need a mocking server" principle still stands strong today, we listen closely and analyze all the great feedback that our users share with us in order to improve the project and increase the amount of use cases it could cover.&lt;/p&gt;

&lt;p&gt;Today, I'm excited to tell you about a project that &lt;a href="https://github.com/idolize" rel="noopener noreferrer"&gt;David Idol&lt;/a&gt; and I have collaborated on with a goal to bring Mock Service Worker to more challenging usage contexts. We named it "http-middleware".&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mswjs" rel="noopener noreferrer"&gt;
        mswjs
      &lt;/a&gt; / &lt;a href="https://github.com/mswjs/http-middleware" rel="noopener noreferrer"&gt;
        http-middleware
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Spawn an HTTP server from your request handlers or apply them to an existing server using a middleware.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  The Concept
&lt;/h2&gt;

&lt;p&gt;The premise of &lt;code&gt;http-middleware&lt;/code&gt; is extremely straightforward: &lt;em&gt;reuse your request handlers to create an actual HTTP server&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This project is designed to cover more complex use cases when the standard Mock Service Worker approach isn't sufficient. Such use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding the ability to &lt;code&gt;curl&lt;/code&gt; your mock definitions, for example, for local debugging;&lt;/li&gt;
&lt;li&gt;Integrating API mocking in complex application architecture (i.e. with dockerized apps).&lt;/li&gt;
&lt;li&gt;Prototyping Node.js server development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that this project is &lt;strong&gt;not a go-to solution for API mocking&lt;/strong&gt;, and you should always favor Mock Service Worker instead. It's created to handle complex use cases and you'd know when you need it. As a rule of thumb: when in doubt, prefer MSW.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learn more about how to &lt;a href="https://mswjs.io/docs/getting-started/install" rel="noopener noreferrer"&gt;get started with MSW&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;




&lt;h2&gt;
  
  
  The Usage
&lt;/h2&gt;

&lt;p&gt;The "http-middleware" project is so concise that I've decided to write a brief usage tutorial right here, right now. Let's get a server running in 2 minutes with your request handlers being the source of truth.&lt;/p&gt;

&lt;p&gt;First, create a project if you don't have one already:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, install the necessary dependencies:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express msw @mswjs/http-middleware &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To keep things simple, let's have a single &lt;code&gt;server.js&lt;/code&gt; file where we will declare our server:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally, use the &lt;code&gt;createServer&lt;/code&gt; function to spawn an &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt; server. Provide it with the request handlers you want to be responsible for producing responses:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createServer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mswjs/http-middleware&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;httpServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;res&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;httpServer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9090&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Learn more about writing &lt;a href="https://mswjs.io/docs/getting-started/mocks" rel="noopener noreferrer"&gt;request handlers&lt;/a&gt; with Mock Service Worker. You can reuse the &lt;em&gt;same&lt;/em&gt; handlers you write in tests, local development, and debugging.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now run your server:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;node server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Try making a &lt;code&gt;GET http://localhost:9090&lt;/code&gt; request. You'll see that the response was resolved based on the request handler you've specified:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;OK&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Content-Type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;text/plain;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="s2"&gt;"Hello world"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Done 🎉&lt;/p&gt;
&lt;h3&gt;
  
  
  Adding to an existing server
&lt;/h3&gt;

&lt;p&gt;Alternatively, you can apply request handlers via a middleware, which is handy in case you already have a server:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// existing-server.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createMiddleware&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mswjs/http-middleware&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;createMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;res&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Cherry on Top
&lt;/h2&gt;

&lt;p&gt;With request handlers acting as the source of truth, you get the same benefits as when using MSW: &lt;em&gt;shared API mocking logic&lt;/em&gt; across different environments and purposes.&lt;/p&gt;

&lt;p&gt;I can't stress enough how important it is to have a clean, deterministic testing setup. There is absolutely no reason to install 3 different libraries for API mocking just because you want to mock the same API in an integration test, and then in an end-to-end test, and then to debug an irksome data-driven bug.&lt;/p&gt;

&lt;p&gt;Mock Service Worker allows you to write your API mocks &lt;strong&gt;&lt;em&gt;once&lt;/em&gt;&lt;/strong&gt; and reuse them &lt;em&gt;anywhere&lt;/em&gt; later: when working on the app, when testing it in Node.js, when running automated tests in Cypress, when debugging. All that using the same familiar consistent syntax. Don't miss out.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mswjs" rel="noopener noreferrer"&gt;
        mswjs
      &lt;/a&gt; / &lt;a href="https://github.com/mswjs/msw" rel="noopener noreferrer"&gt;
        msw
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Industry standard API mocking for JavaScript.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Embrace the ecosystem
&lt;/h3&gt;

&lt;p&gt;By leveraging libraries like &lt;a href="https://github.com/mswjs/data" rel="noopener noreferrer"&gt;@mswjs/data&lt;/a&gt;, you can have data-driven type-safe API mocking reused across the &lt;em&gt;entire stack&lt;/em&gt;. Develop and iterate on your next product with the speed of light by the flexibility Mock Service Worker and its ecosystem gives you.&lt;/p&gt;




&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;We're excited to see what impact this small package will have in your development workflow! Make sure to &lt;a href="https://twitter.com/ApiMocking" rel="noopener noreferrer"&gt;&lt;strong&gt;follow Mock Service Worker on Twitter&lt;/strong&gt;&lt;/a&gt; to get the latest news and be notified about many upcoming features. &lt;/p&gt;

&lt;p&gt;We also highly encourage you to contribute to the &lt;code&gt;http-middleware&lt;/code&gt; package with your ideas and feedback on GitHub:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mswjs" rel="noopener noreferrer"&gt;
        mswjs
      &lt;/a&gt; / &lt;a href="https://github.com/mswjs/http-middleware" rel="noopener noreferrer"&gt;
        http-middleware
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Spawn an HTTP server from your request handlers or apply them to an existing server using a middleware.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Stay awesome ❤️&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>api</category>
      <category>backend</category>
    </item>
    <item>
      <title>Announcing "@mswjs/data"—data modeling library for testing JavaScript applications</title>
      <dc:creator>Artem Zakharchenko</dc:creator>
      <pubDate>Mon, 12 Apr 2021 15:59:45 +0000</pubDate>
      <link>https://dev.to/kettanaito/announcing-mswjs-data-data-modeling-library-for-testing-javascript-applications-3290</link>
      <guid>https://dev.to/kettanaito/announcing-mswjs-data-data-modeling-library-for-testing-javascript-applications-3290</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;It's been more than a year since &lt;a href="https://mswjs.io" rel="noopener noreferrer"&gt;Mock Service Worker&lt;/a&gt; (MSW) began to appear in people's &lt;code&gt;package.json&lt;/code&gt;, improving the way you write tests, iterate on features, and debug API-related issues. We are incredibly thankful for everybody who supported us and gave the library a chance in their projects. That allowed us to gather a ton of feedback based on the usage scenarios you face every day. It is with that feedback that we can move the project forward to ease your testing and development workflow even more. And it is with that feedback that we are able to make this announcement.&lt;/p&gt;

&lt;p&gt;MSW was deliberately designed with only the essentials of API mocking in mind: interception of requests and response mocking. A huge focus was made on leveraging Service Worker API to enable a one-of-a-kind experience and support the same request handlers across different environments. While some alternative libraries come with built-in assertions or data-modeling options, our team has chosen a horizontal way to scale the project: distribute complimentary, on-demand libraries instead of stuffing dozens of functions and methods into a single package.&lt;/p&gt;

&lt;p&gt;Some of the most popular questions developers have when starting with MSW are related to data. You immediately notice how the library is agnostic to how you create and update data in your handlers. You may use a plain array or &lt;code&gt;Map&lt;/code&gt; to manage resources. Perhaps, you may even design a custom database abstraction that manages those resources in a more standardized way.&lt;/p&gt;

&lt;p&gt;No matter what data-related setup you end up with, it's there to answer the following questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to describe data resources?&lt;/li&gt;
&lt;li&gt;How to implement CRUD operations on data?&lt;/li&gt;
&lt;li&gt;How to persist the changes made to the data?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today we are proud to announce the &lt;a href="https://github.com/mswjs/data" rel="noopener noreferrer"&gt;Data library&lt;/a&gt;—a standalone package to model and query data in your tests and beyond. Although the project is at the early stage of development and doesn't solve every problem right away, letting you try it out and gather your feedback is crucial for us to refine and shape the future experience.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mswjs" rel="noopener noreferrer"&gt;
        mswjs
      &lt;/a&gt; / &lt;a href="https://github.com/mswjs/data" rel="noopener noreferrer"&gt;
        data
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Data modeling and relation library for testing JavaScript applications.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Without further a due, let's talk about what's to become the recommended way to work with data in Mock Service Worker.&lt;/p&gt;




&lt;h2&gt;
  
  
  Data modeling
&lt;/h2&gt;

&lt;p&gt;First, let's get acquainted with the two main terms that the Data library operates with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Model&lt;/em&gt;—description of the data. Think of it as a blueprint that describes what properties the data has.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Entity&lt;/em&gt;—an instance of a particular model. This is the exact data that implements its model description.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When working with Data, you define models and relationships between them, which, effectively, result in a virtual database being created.&lt;/p&gt;

&lt;p&gt;Install the package into your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @mswjs/data 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, let's create a new "user" model:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;primaryKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mswjs/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Models are defined by calling the &lt;code&gt;factory&lt;/code&gt; function and providing it with the object where keys represent &lt;em&gt;model names&lt;/em&gt;, and values stand for &lt;em&gt;model definitions&lt;/em&gt;. Each property in the model definition has an initializer—a function that seeds a value and infers its type.&lt;/p&gt;

&lt;p&gt;Notice how the &lt;code&gt;id&lt;/code&gt; property equals &lt;code&gt;primaryKey&lt;/code&gt;. Each model &lt;em&gt;must have a primary key&lt;/em&gt;, which acts as a unique ID in a conventional database table. Data exposes the &lt;code&gt;primaryKey&lt;/code&gt; function that you should use to mark a certain property as the model's primary key.&lt;/p&gt;

&lt;p&gt;In the example above, we're using plain functions that return static data. This means that each time a user is created, it will have &lt;code&gt;firstName: "John"&lt;/code&gt; and &lt;code&gt;age: 18&lt;/code&gt;. While this is a good foundation to build upon, the static nature of values may limit your data scenarios. Consider using tools like &lt;a href="https://github.com/marak/Faker.js/" rel="noopener noreferrer"&gt;Faker&lt;/a&gt; to define models with randomly generated realistic data.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;primaryKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mswjs/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;random&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;faker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// Create a user model with a random UUID and first name.&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can define multiple models and relationships between them within the same &lt;code&gt;factory&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oneOf&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mswjs/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;random&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;faker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;book&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;isbn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="c1"&gt;// "book.publisher" is a relational property&lt;/span&gt;
    &lt;span class="c1"&gt;// that references an entity of the "publisher" model.&lt;/span&gt;
    &lt;span class="na"&gt;publisher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;oneOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;publisher&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;publisher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Learn more about &lt;a href="https://github.com/mswjs/data" rel="noopener noreferrer"&gt;defining model relationships&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Seeding
&lt;/h2&gt;

&lt;p&gt;Once the models are defined, create an entity of a particular model by calling the &lt;code&gt;.create()&lt;/code&gt; method on it:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Creating an entity without any arguments will fill its properties using the value initializers you've specified in the model definition.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.create()&lt;/code&gt; method accepts an optional argument that stands for the initial values of the entity. For example, if we wish to create a user with a fixed "firstName" value, we can provide that value in the initial values object:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// Uses an exact value for the "firstName" property,&lt;/span&gt;
  &lt;span class="c1"&gt;// while seeding the "id" based on its getter.&lt;/span&gt;
  &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Querying client
&lt;/h2&gt;

&lt;p&gt;Apart from the data modeling functionality, this library provides a &lt;em&gt;querying client&lt;/em&gt; that allows you to find, modify, and delete entities on runtime. The querying client brings Data to life, as it enables dynamic scenarios against the generated data.&lt;/p&gt;

&lt;p&gt;Each model supports the following querying methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.findFirst()&lt;/code&gt;, finds the first entity that matches a query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.findMany()&lt;/code&gt;, finds multiple entities that match a query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.count()&lt;/code&gt;, returns the number of entities for a model.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.update()&lt;/code&gt;, updates an entity that matches a query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.updateMany()&lt;/code&gt;, updates multiple entities that match a query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.delete()&lt;/code&gt;, deletes an entity that matches a query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.deleteMany()&lt;/code&gt;, deletes multiple entities that match a query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most basic example of querying is finding an entity by its primary key. In our case, we can find a user by its "id" like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Find a user with the given "id" (primary key).&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findFirst&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abc-123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's focus on &lt;code&gt;where&lt;/code&gt; part of the query above. When querying entities, &lt;code&gt;where&lt;/code&gt; is a predicate object that describes the criteria against an entity. The structure of that predicate is the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;expectedValue&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[property]&lt;/code&gt;, a known property of the model. In the case of our "user" model, this can be "id" or "firstName".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[operator]&lt;/code&gt;, an operator function name that compares the actual and expected values of the referenced property.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Operators depend on the value type that's being queried. When querying a string (like we do with &lt;code&gt;where.id&lt;/code&gt;, where "id" is of the String type), operators like &lt;code&gt;equals&lt;/code&gt;, &lt;code&gt;notEquals&lt;/code&gt;, &lt;code&gt;contains&lt;/code&gt;, &lt;code&gt;in&lt;/code&gt;, and others are available. When querying a number, you have access to the &lt;code&gt;gt&lt;/code&gt;, &lt;code&gt;lte&lt;/code&gt;, &lt;code&gt;between&lt;/code&gt;, etc. operators instead.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Querying methods are strongly typed, validating the known model properties and value-based operators on build time. Experiment with your models to learn about all the different options at your disposal!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a similar fashion, we can query multiple entities. Here's how we can get all the users that satisfy a certain age criteria:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Returns all users whose "user.age"&lt;/span&gt;
&lt;span class="c1"&gt;// is greater or equal 18.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;gte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Data supports &lt;a href="https://github.com/mswjs/data#cursor-based-pagination" rel="noopener noreferrer"&gt;cursor&lt;/a&gt; and &lt;a href="https://github.com/mswjs/data#offset-based-pagination" rel="noopener noreferrer"&gt;offset&lt;/a&gt; pagination to work with large data sets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is much more functionality that Data provides, so don't hesitate to explore the library API. Refer to the &lt;a href="https://github.com/mswjs/data" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for API definition and usage examples.&lt;/p&gt;


&lt;h2&gt;
  
  
  Integration with Mock Service Worker
&lt;/h2&gt;

&lt;p&gt;Here's a gigantic cherry on top: you can turn any data model into &lt;a href="https://mswjs.io/docs/basics/request-handler" rel="noopener noreferrer"&gt;request handlers&lt;/a&gt; (both REST &lt;em&gt;and&lt;/em&gt; GraphQL) to encapsulate its operations, like creation and querying, under the respective API routes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Generating REST API
&lt;/h3&gt;

&lt;p&gt;Using our &lt;code&gt;db&lt;/code&gt; and its "user" model, we can turn it into a REST API "server" in a single command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/mocks/browser.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setupWorker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// Import the "db" object.&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setupWorker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;// Generate REST API request handlers&lt;/span&gt;
  &lt;span class="c1"&gt;// based on the "user" model.&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toHandlers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Looks unfamiliar? Learn how to &lt;a href="https://mswjs.io/docs/getting-started/install" rel="noopener noreferrer"&gt;get started with Mock Service Worker&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Calling &lt;code&gt;.toHandlers()&lt;/code&gt; on a model generates CRUD routes for working with that model. In the example above, the following request handlers will be created:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /users/&lt;/code&gt;, returns all users in the database.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /users/:id&lt;/code&gt;, returns a user by their primary key (&lt;code&gt;id&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /users&lt;/code&gt;, creates a new user.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PUT /users/:id&lt;/code&gt;, updates an existing user.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DELETE /users/:id&lt;/code&gt;, deletes a user by their primary key.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Notice how the model name is pluralized ("user*&lt;em&gt;s&lt;/em&gt;*") to reflect the proper semantics when working with the "user" resource.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the handlers established, you can create and query users in your application as you would do against an actual HTTP server:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a new user in the database.&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// The body is used as the initial entity values.&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abc-123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// Then, query the created user.&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/abc-123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Explore this interactive sandbox to learn more about generating REST API handlers from your data models:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/data-rest-api-handlers-i91nv"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;h3&gt;
  
  
  Generating GraphQL API
&lt;/h3&gt;

&lt;p&gt;A model can also generate GraphQL handlers:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setupWorker&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toHandlers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This command generates the following GraphQL schema with its types based on your model:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserQuery&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;skip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;!]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserInput&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserQueryInput&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserInput&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;updateUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserQueryInput&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserInput&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;!]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;deleteUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserQueryInput&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserInput&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;deleteUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserQueryInput&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserInput&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;!]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;All the generated GraphQL types and their names are based on your model name and properties.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With your model turned into request handlers, you can query its entities as you would usually do in GraphQL. Here's an example that uses Apollo to get a user entity by ID:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@apollo/client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GET_USER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  query GetUser {
    # Hey, it's the same query as in the ".findMany()" method!
    user(where: { id: { equals: "abc-123" } }) {
      firstName
      age
    }
  }
`&lt;/span&gt;

&lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GET_USER&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Explore the GraphQL example on Codesandbox:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/data-graphql-api-handlers-2xc4i"&gt;
&lt;/iframe&gt;
&lt;/p&gt;


&lt;h2&gt;
  
  
  Call for Contributors!
&lt;/h2&gt;

&lt;p&gt;Data is a new library that has a long way to go and multiple areas to improve. For instance, these are some of the features we'd love to implement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client-side persistence;&lt;/li&gt;
&lt;li&gt;Server-side rendering support;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.createMany()&lt;/code&gt; method to seed multiple entities at once, respecting their relations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you would like to learn about data modeling or find this area fascinating, &lt;a href="https://github.com/mswjs/data/issues" rel="noopener noreferrer"&gt;&lt;strong&gt;join as a contributor&lt;/strong&gt;&lt;/a&gt; and shape the way developers would model their fixtures.&lt;/p&gt;

&lt;p&gt;You can also support the project financially by &lt;a href="https://opencollective.com/mswjs" rel="noopener noreferrer"&gt;&lt;strong&gt;sponsoring it on Open Collective&lt;/strong&gt;&lt;/a&gt;, allowing the team to work on bug fixes and stunning new features. Your support will not go unnoticed!&lt;/p&gt;


&lt;h2&gt;
  
  
  Resources &amp;amp; links
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mswjs" rel="noopener noreferrer"&gt;
        mswjs
      &lt;/a&gt; / &lt;a href="https://github.com/mswjs/data" rel="noopener noreferrer"&gt;
        data
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Data modeling and relation library for testing JavaScript applications.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mswjs/msw" rel="noopener noreferrer"&gt;Mock Service Worker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/ApiMocking" rel="noopener noreferrer"&gt;Follow on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>API Mocking Strategies for JavaScript Applications</title>
      <dc:creator>Artem Zakharchenko</dc:creator>
      <pubDate>Tue, 16 Mar 2021 09:08:30 +0000</pubDate>
      <link>https://dev.to/kettanaito/api-mocking-strategies-for-javascript-applications-48kl</link>
      <guid>https://dev.to/kettanaito/api-mocking-strategies-for-javascript-applications-48kl</guid>
      <description>&lt;p&gt;API mocking is easily the most common kind of mocking in JavaScript (apart from the mocking about how there's a new framework every day). No matter what application you're building, it is likely to make some HTTP calls. &lt;/p&gt;

&lt;p&gt;So why do you even need mocking? A good question, &lt;a href="https://dev.to/kettanaito/when-should-i-not-use-mocks-in-testing-544e"&gt;perhaps you don't&lt;/a&gt;. However, if you wish to test the code you write, you'd also have to test the code that does HTTP requests. Making actual requests in your tests is a sure path to flaky and unreliable tests, and here's where API mocking comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Request's Journey
&lt;/h2&gt;

&lt;p&gt;Before we rush into code, let's stop for a moment and think about what we're trying to achieve here.&lt;/p&gt;

&lt;p&gt;Mocking is the action of substituting a piece of software with another, seemingly compatible piece. Since we wish to mock an API call, we will be substituting &lt;em&gt;some piece&lt;/em&gt; of the logic responsible for making that call. To better understand which part and why we'll be mocking, we need to visualize a journey of the request first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's a high-level overview of what happens when your application makes a request:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgh5db7ha50vet8gu9w4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frgh5db7ha50vet8gu9w4.png" alt="The request's journey" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your application calls a &lt;em&gt;request client&lt;/em&gt; to make a request. This can be &lt;code&gt;window.fetch&lt;/code&gt;, &lt;code&gt;react-query&lt;/code&gt;, or Apollo. &lt;/li&gt;
&lt;li&gt;The request client forms a proper request based on your input (resource path, query parameters, headers, body, etc.), and sends it over HTTP to the &lt;em&gt;server&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The server receives a request and returns a &lt;em&gt;response&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Your application receives the response.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;It's important to mention that this diagram may differ based on the application architecture you have. However, there always will be these fundamental pieces: a logic that dispatches a request and a server that processes that request. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This overview gives us some visual clues towards what parts conclude a request. We will be mocking one of those parts to achieve our goal. Now to decide which one...&lt;/p&gt;

&lt;h2&gt;
  
  
  API mocking strategies
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I've been honored to speak about various API mocking strategies at this year's TestJS Summit conference. In the video below you can get a grasp over mocking as a technique, its purpose, and the most common (&lt;em&gt;and the most efficient&lt;/em&gt;) ways to achieve it. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/76yEzm07Kfk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let's take a closer look at each strategy in the written form today.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Out of the request's journey components (application, request client, server) we surely don't wish to mock an application. That's the code we're trying to test, and mocking it would be, well, pointless. &lt;/p&gt;

&lt;p&gt;This leaves us with the two remaining parts, each representing a mocking strategy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mocking the request client.&lt;/li&gt;
&lt;li&gt;Mocking the server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both these strategies are applicable and widely used. Just as any decision in programming, choosing any of these strategies comes with benefits and drawbacks. Let's focus on those.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mocking the request client
&lt;/h3&gt;

&lt;p&gt;When you mock the request client, you're making the following change in the request's journey:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm38dz9a60knsygfu31zj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm38dz9a60knsygfu31zj.png" alt="The request journey altered by the mocking request client strategy" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By mocking (substituting) the request client, the &lt;em&gt;actual&lt;/em&gt; request client is taken out of the equation. A compatible client is placed in its stead, giving us the desired power to mock the responses our application receives.&lt;/p&gt;

&lt;p&gt;The most basic example that illustrates this mocking strategy in practice is when you stub the &lt;code&gt;window.fetch&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Respond with a mocked response&lt;/span&gt;
  &lt;span class="c1"&gt;// any time our code calls "window.fetch".&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, most of the time you would use a third-party library that abstracts this logic for you. Some of the prominent libraries for this strategy are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/miragejs/miragejs" rel="noopener noreferrer"&gt;MirageJS&lt;/a&gt;, through &lt;a href="https://github.com/pretenderjs/pretender/blob/e4fa32ab491f5479bb1d0440be1f64e2904994c1/src/index.ts#L32" rel="noopener noreferrer"&gt;Pretender&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/nock/nock" rel="noopener noreferrer"&gt;nock&lt;/a&gt;, through &lt;a href="https://github.com/nock/nock/blob/2134a418c358d4134233ffaf7bb25809a5869a71/lib/common.js#L93-L110" rel="noopener noreferrer"&gt;stubbing &lt;code&gt;http&lt;/code&gt;/&lt;code&gt;https&lt;/code&gt; modules&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://netflix.github.io/pollyjs" rel="noopener noreferrer"&gt;PollyJS&lt;/a&gt;, through various &lt;a href="https://github.com/Netflix/pollyjs/tree/cbca602a5a446da46a4a2834f893670b8c577880/packages/%40pollyjs" rel="noopener noreferrer"&gt;adapters&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;p&gt;This strategy gives us control over the requests/responses at the earliest stage of their flow. The cost of such control is also minimal, as the mocking logic lives entirely in the client-side code, next to our application.&lt;/p&gt;

&lt;h4&gt;
  
  
  Drawbacks
&lt;/h4&gt;

&lt;p&gt;If you take a closer look at the diagram altered by this strategy, you'll notice that not only the "Server" part is blackened out, but also the "Request" part. That is because replacing the request client means &lt;strong&gt;it never actually makes a request&lt;/strong&gt;. If a request "leaves" the client, it won't be able to control it anymore.&lt;/p&gt;

&lt;p&gt;There's also a behavioral divergence for your application: it &lt;em&gt;does&lt;/em&gt; a request in production, but it &lt;em&gt;doesn't&lt;/em&gt; in the tests. &lt;/p&gt;

&lt;h3&gt;
  
  
  Mocking the server
&lt;/h3&gt;

&lt;p&gt;Alternatively, we can replace the "server" part of the request journey to make it look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcyjxjyk17wq4dum5twr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcyjxjyk17wq4dum5twr.png" alt="Mocking server strategy" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since our request client is configured to communicate with a production server, such request destination detour often happens by introducing some sort of conditional URL logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;IS_TEST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;IS_TEST&lt;/span&gt;
    &lt;span class="c1"&gt;// Communicate with a local mock server while testing.&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3000/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.backend.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the most prominent libraries for this mocking strategy are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/typicode/json-server" rel="noopener noreferrer"&gt;JSON Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learning.postman.com/docs/designing-and-developing-your-api/mocking-data/setting-up-mock/" rel="noopener noreferrer"&gt;Postman's mock servers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Plain &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;ExpressJS server&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Benefits
&lt;/h4&gt;

&lt;p&gt;With the mocking server strategy, we're allowing the request client to fully execute because it's the server part that we're placing. This makes our application behavior under test &lt;em&gt;almost idenctical&lt;/em&gt; to the one in production. Almost.&lt;/p&gt;

&lt;h4&gt;
  
  
  Drawbacks
&lt;/h4&gt;

&lt;p&gt;For this strategy to work, our request client must know when and how to decide which server endpoint to use. Regardless of the technical details of this strategy, it means that the requests are hitting &lt;em&gt;an entirely different server&lt;/em&gt;. Introducing any kind of deviation puts the logic you're resting at risk. Consider this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;IS_TEST&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3000/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hts://apibackendcom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// Ehm, is this okay?&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual production server URL is corrupted in the example above. Guess what, the tests would still pass while the application would be successfully broken for your users.&lt;/p&gt;

&lt;p&gt;There is also a minor operational hassle, as you need to spawn and terminate the local mocking server before/after your test suites. You must ensure the mocking server's operability so that there are no unhandled exceptions that may fail your tests, resulting in false negatives.&lt;/p&gt;

&lt;p&gt;Overall, introducing an entire server for the sake of mocking may be considered an overhaul. Even if you're using it for this specific purpose, it's still an actual server you need to write and maintain, increasing the operational cost of this setup.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using third-party libraries often abstracts the operational aspect of the mocking server, so you're not experiencing it directly. That doesn't mean that it's magically gone. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Which strategy to choose?
&lt;/h2&gt;

&lt;p&gt;The mocking strategy you choose largely depends on the environment where you wish to mock API. Certain environments, such as the browser, allow you to intercept requests on the network level via &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API" rel="noopener noreferrer"&gt;Service Worker API&lt;/a&gt;. That way you compromise on neither request client nor server, allowing &lt;em&gt;all&lt;/em&gt; your logic to execute, hit the same production endpoints, and receive the mocked response you're in charge of.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Libraries like &lt;a href="https://github.com/mswjs/msw" rel="noopener noreferrer"&gt;Mock Service Worker&lt;/a&gt; leverage this unique browser ability gracefully to provision seamless API mocking. Let me know if you would like to learn more about this unusual strategy in the comments below!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are, however, environments that don't have a designated API to intercept outgoing requests. Running tests in Node.js, for example, would likely require your mocking setup to stub request issuing modules (such as &lt;code&gt;http.request&lt;/code&gt;) in order to know what requests are happening, and mock their responses.&lt;/p&gt;




&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;Regardless of which API mocking strategy you end up choosing, please remember that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The less test-specific setup you have, the better;&lt;/li&gt;
&lt;li&gt;The less your app's behavior changes for the sake of tests, the better;&lt;/li&gt;
&lt;li&gt;The closer to the server your request interception is, the better.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you've enjoyed this analysis of different API mocking strategies you may adopt. Make sure to &lt;a href="https://twitter.com/kettanaito" rel="noopener noreferrer"&gt;follow me on Twitter&lt;/a&gt; to stay in touch with the articles I write. Stay productive!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>api</category>
      <category>testing</category>
      <category>mocking</category>
    </item>
    <item>
      <title>Type-safe API mocking with Mock Service Worker and TypeScript</title>
      <dc:creator>Artem Zakharchenko</dc:creator>
      <pubDate>Sun, 28 Feb 2021 14:10:14 +0000</pubDate>
      <link>https://dev.to/kettanaito/type-safe-api-mocking-with-mock-service-worker-and-typescript-21bf</link>
      <guid>https://dev.to/kettanaito/type-safe-api-mocking-with-mock-service-worker-and-typescript-21bf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; This article is about MSW v1. We released &lt;a href="https://mswjs.io/blog/introducing-msw-2.0" rel="noopener noreferrer"&gt;MSW v2&lt;/a&gt;, which brings improvements to type-safety along with other features and bug fixes. Please read the &lt;a href="https://mswjs.io/docs/best-practices/typescript" rel="noopener noreferrer"&gt;Using with TypeScript&lt;/a&gt; page for type-safe API mocking on MSW v2. Thank you!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://mswjs.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Mock Service Worker&lt;/strong&gt;&lt;/a&gt; is a seamless API mocking library for browser and Node.js. It uses Service Worker API to intercept requests on the network level, meaning no more stubbing of "fetch", "axios", or any other request issuing client. It provides a first-class experience when mocking REST and GraphQL API, and allows you to reuse the same mocks for testing, development, and debugging.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Watch this 4 minutes tutorial on mocking a basic REST API response with Mock Service Worker to get a better understanding of how this library works and feels:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/e8lbbqSa4e4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Today we're going to have a practical dive-in into adding TypeScript to your API mocking experience to bring it one step further.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why annotate mocks?
&lt;/h3&gt;

&lt;p&gt;The mocks you write are a part of your application like any other piece of logic. Having a type validation is one of the cheapest and most efficient ways to ensure your mocks satisfy the data expectations towards them.&lt;/p&gt;




&lt;h1&gt;
  
  
  REST API
&lt;/h1&gt;

&lt;p&gt;Each &lt;a href="https://mswjs.io/docs/api/rest" rel="noopener noreferrer"&gt;REST request handler&lt;/a&gt; has the following type signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RestHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RequestBody&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ResponseBody&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RequestParams&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;MockedResponse&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to annotate three things in our REST API handlers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Request body type.&lt;/li&gt;
&lt;li&gt;Response body type.&lt;/li&gt;
&lt;li&gt;Request parameters.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's take a look at the &lt;code&gt;UPDATE /post/:postId&lt;/code&gt; request that utilizes all three said generics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Describe the shape of the "req.body".&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UpdatePostRequestBody&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;viewsCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Describe the shape of the mocked response body.&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UpdatePostResponseBody&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Describe the shape of the "req.params".&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UpdatePostRequestParams&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UpdatePostRequestBody&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UpdatePostResponseBody&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UpdatePostRequestParams&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/post/:postId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;postId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;viewsCount&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;res&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The same generics apply to any &lt;code&gt;rest&lt;/code&gt; request handler: &lt;code&gt;rest.get()&lt;/code&gt;, &lt;code&gt;rest.post()&lt;/code&gt;, &lt;code&gt;rest.delete()&lt;/code&gt;, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  GraphQL API
&lt;/h1&gt;

&lt;p&gt;A type signature for the &lt;a href="https://mswjs.io/docs/api/graphql" rel="noopener noreferrer"&gt;GraphQL handlers&lt;/a&gt; is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GraphQLHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Variables&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;MockedResponse&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means we can annotate the &lt;code&gt;Query&lt;/code&gt; type (what gets returned in the response) and the &lt;code&gt;Variables&lt;/code&gt; of our query.&lt;/p&gt;

&lt;p&gt;Let's take a look at some concrete examples. &lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL queries
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Describe the payload returned via "ctx.data".&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;GetUserQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
    &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
    &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Describe the shape of the "req.variables" object.&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;GetUserQueryVariables&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GetUserQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetUserQueryVariables&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GetUser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variables&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;res&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maverick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GraphQL mutations
&lt;/h2&gt;

&lt;p&gt;Now, let's apply the same approach to a GraphQL mutation. In the case below we're having a &lt;code&gt;UpdateArticle&lt;/code&gt; mutation that updates an article by its ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UpdateArticleMutation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UpdateArticleMutationVariables&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UpdateArticleMutation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UpdateArticleMutationVariables&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UpdateArticle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variables&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;res&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GraphQL operations
&lt;/h2&gt;

&lt;p&gt;When it comes to capturing multiple GraphQL operations regardless of their kind/name, the &lt;a href="https://mswjs.io/docs/api/graphql/operation" rel="noopener noreferrer"&gt;&lt;code&gt;graphql.operation()&lt;/code&gt;&lt;/a&gt; truly shines. Although the nature of the incoming queries becomes less predictable, you can still specify its &lt;code&gt;Query&lt;/code&gt; and &lt;code&gt;Variables&lt;/code&gt; types using the handler's generics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;updateAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Variables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;articleId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cartId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Variables&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// In this example we're calling an abstract&lt;/span&gt;
  &lt;span class="c1"&gt;// "resolveOperation" function that returns&lt;/span&gt;
  &lt;span class="c1"&gt;// the right query payload based on the request.&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;res&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;resolveOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bonus: Using with GraphQL Code Generator
&lt;/h2&gt;

&lt;p&gt;My absolute favorite setup for mocking GraphQL API is when you add &lt;a href="https://graphql-code-generator.com" rel="noopener noreferrer"&gt;GraphQL Code Generator&lt;/a&gt; to the mix.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GraphQL Code Generator is a superb tool that allows you to generate type definitions from your GraphQL schema, but also from the exact queries/mutations your application makes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's an example of how to integrate the types generated by GraphQL Codegen into your request handlers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// Import types generated from our GraphQL schema and queries.&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GetUserQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetUserQueryVariables&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Annotate request handlers to match &lt;/span&gt;
&lt;span class="c1"&gt;// the actual behavior of your application.&lt;/span&gt;
&lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GetUserQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetUserQueryVariables&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GetUser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With your data becoming the source of truth for your request handlers, you're always confident that your mocks reflect the actual behavior of your application. You also remove the need to annotate queries manually, which is a tremendous time-saver!&lt;/p&gt;




&lt;h1&gt;
  
  
  Advanced usage
&lt;/h1&gt;

&lt;p&gt;We've covered most of the common usage examples above, so let's talk about those cases when you abstract, restructure and customize your mocking setup. &lt;/p&gt;

&lt;h2&gt;
  
  
  Custom response resolvers
&lt;/h2&gt;

&lt;p&gt;It's not uncommon to isolate a response resolver logic into a higher-order function to prevent repetition while remaining in control over the mocked responses. &lt;/p&gt;

&lt;p&gt;This is how you'd annotate a custom response resolver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/mocks/resolvers.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ResponseResolver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RestRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RestContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userResolver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ResponseResolver&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RestRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RestContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;res&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;userResolver&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./resolvers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;commonUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;adminUser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./fixtures&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/user/:userId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;userResolver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;commonUser&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;userResolver&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;commonUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;adminUser&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Custom response transformers
&lt;/h2&gt;

&lt;p&gt;You can create custom context utilities on top of &lt;a href="https://mswjs.io/docs/basics/response-transformer" rel="noopener noreferrer"&gt;response transformers&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Here's an example of how to create a custom response transformer that uses the &lt;code&gt;json-bigint&lt;/code&gt; library to support BigInt in the JSON body of your mocked responses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/mocks/transformers.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;JsonBigInt&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json-bigint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ResponseTransformer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;compose&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Here we're creating a custom context utility&lt;/span&gt;
&lt;span class="c1"&gt;// that can handle a BigInt values in JSON.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonBigInt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;ResponseTransformer&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/hal+json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JsonBigInt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note how you can compose your custom response transformer's logic by utilizing the &lt;code&gt;compose&lt;/code&gt; and &lt;code&gt;context&lt;/code&gt; exported from MSW. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can use that &lt;code&gt;jsonBigInt&lt;/code&gt; transformer when composing mocked responses in your handlers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;jsonBigInt&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./transformers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/stats&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;res&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// Use the custom context utility the same way&lt;/span&gt;
    &lt;span class="c1"&gt;// you'd use the default ones (i.e. "ctx.json()").&lt;/span&gt;
    &lt;span class="nf"&gt;jsonBigInt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john.maverick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1597928668063727616&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;Hope you find this article useful and learn a thing or two about improving your mocks by covering them with type definitions—either manual or generated ones.&lt;/p&gt;

&lt;p&gt;There can be other scenarios when you may find yourself in need to cover your mocks with types. Explore what type definitions MSW exports and take a look at the &lt;a href="https://github.com/mswjs/msw" rel="noopener noreferrer"&gt;library's implementation&lt;/a&gt; for reference.&lt;/p&gt;

&lt;p&gt;Share this article with your colleagues and give it a shoutout on Twitter, I'd highly appreciate it! Thank you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Useful resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=e8lbbqSa4e4" rel="noopener noreferrer"&gt;&lt;strong&gt;Mocking a basic HTTP response (YouTube)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mswjs.io/" rel="noopener noreferrer"&gt;Mock Service Worker documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mswjs/msw" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
      <category>typescript</category>
      <category>api</category>
      <category>mocking</category>
    </item>
    <item>
      <title>When should I (not) use mocks in testing?</title>
      <dc:creator>Artem Zakharchenko</dc:creator>
      <pubDate>Tue, 24 Nov 2020 15:44:06 +0000</pubDate>
      <link>https://dev.to/kettanaito/when-should-i-not-use-mocks-in-testing-544e</link>
      <guid>https://dev.to/kettanaito/when-should-i-not-use-mocks-in-testing-544e</guid>
      <description>&lt;h2&gt;
  
  
  What is "mocking"?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Mocking&lt;/em&gt; in programming refers to an action of substituting a part of the software with its fake counterpart.&lt;/p&gt;

&lt;p&gt;Mocking technique is primarily used during testing, as it allows us to take out certain aspects of the tested system, thus narrowing the test's focus and decreasing the test's complexity.&lt;/p&gt;

&lt;p&gt;Depending on the software that is being tested, there are multiple things that can be mocked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Environment and context&lt;/strong&gt;. To assert a list of user's purchases you can mock the user already being authenticated, instead of going through the authentication in the unrelated test suite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API communication&lt;/strong&gt;. When testing a checkout process you don't want to make an actual purchase and be charged for it. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External dependencies&lt;/strong&gt;. When testing how our system reacts to various payloads from an external library or SDK you may emulate what the latter return.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding when to apply and, most importantly, when not to apply mocking is a vital skill to help you ensure your tests are reproducible and credible. Today I would like to share some &lt;em&gt;opinionated&lt;/em&gt; views and guidelines that help me decide and integrate mocking into my tests and still trust them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The purpose of mocking
&lt;/h2&gt;

&lt;p&gt;By mocking certain parts of our system we drop them from the testing equation. That way the mocked parts become a test's &lt;em&gt;pre-requisites&lt;/em&gt;, a configurable given that should not be acted upon. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some of the biggest benefits of mocking:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Makes a tested system, or its parts, more predictable by configuring or fixing dynamic system parts (i.e. HTTP requests).&lt;/li&gt;
&lt;li&gt;Gives a granular control over the system's state at a given point in time.&lt;/li&gt;
&lt;li&gt;Keeps tests more focused by treating certain internal or external system's aspects as pre-requisites.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The dangers of mocking
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Deviating system
&lt;/h3&gt;

&lt;p&gt;What mocking essentially does is that it &lt;em&gt;replaces&lt;/em&gt; one part of the system with a &lt;em&gt;seemingly compatible&lt;/em&gt; part.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Mocking creates a deviation in the system that always results in an altered system.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Although it may still look and behave similarly, the system's integrity gets compromised and with an excessive or misguided mocking one may find themselves testing an entirely different system than one should.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Mocking or stubbing request issuing module&lt;/span&gt;
&lt;span class="c1"&gt;// as a part of a test implies that the tested system&lt;/span&gt;
&lt;span class="c1"&gt;// does not execute the actual "fetch" any longer.&lt;/span&gt;
&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ok&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Learn about why you should &lt;a href="https://kentcdodds.com/blog/stop-mocking-fetch" rel="noopener noreferrer"&gt;Stop mocking fetch&lt;/a&gt; with Kent C. Dodds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Testing implementation details
&lt;/h3&gt;

&lt;p&gt;Another dangerous drawback of a misplaced mocking is that one may fall into the trap of implementation details testing without even realizing it. Replacing any part of the internal/external system is incredibly powerful and&lt;br&gt;
comes with the responsibility on your shoulders not to misuse mocking to test things on a level much deeper than it is necessary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// context.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Lookups the list of sessions.&lt;/span&gt;
  &lt;span class="nf"&gt;lookupSessions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// Returns the active user from the latest session.&lt;/span&gt;
  &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lookupSessions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latestSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;latestSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// context.test.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./context&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nf"&gt;beforeAll&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lookupSessions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockImplementation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;returns the active user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lookupSessions&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeCalled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeDefined&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The issue here is that if &lt;code&gt;context.getUser&lt;/code&gt; stopped relying on the &lt;code&gt;lookupSessions&lt;/code&gt; method the test would fail. Even if &lt;code&gt;context.getUser&lt;/code&gt; &lt;em&gt;still returns the proper user&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;The issues caused by mocking can be split into two categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Misplaced mocking&lt;/strong&gt;. Mocking is not applicable in the current circumstances and should be avoided.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inaccurate mocking&lt;/strong&gt;. Mocking is applicable, but executed poorly: the extend of mocks is excessive, or the mocked part's behavior violates the system's integrity.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  When to mock?
&lt;/h2&gt;

&lt;p&gt;Let's focus on the mocking in the context of tests.&lt;/p&gt;

&lt;p&gt;The purpose of testing is to give you confidence in the system you are developing. The more you mock, the more you deviate from the original system, the more it decreases the amount of confidence your tests give you. It is crucial to know what and when to mock during test runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When it comes to mocking there is a golden rule:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you can omit mocking, omit mocking.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Despite being somewhat extreme, this rule guards you against unnecessary mocking, making each time you decide to mock something a conscious and well-weighed choice, rather than a reach-out tool for each and every situation.&lt;/p&gt;

&lt;p&gt;There are cases, however, when mocking is beneficial and even necessary in tests. Those cases derive from the testing levels and the boundaries each level establishes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mocking in different testing levels
&lt;/h3&gt;

&lt;p&gt;Mocking plays a crucial part in defining testing boundaries. Testing boundary, or in other words an extent of a system covered by a particular test, is predefined by the testing level (unit/integration/end-to-end).&lt;/p&gt;

&lt;h4&gt;
  
  
  Unit tests
&lt;/h4&gt;

&lt;p&gt;It is unlikely for mocking to be applicable in unit tests, as that means there is a part of the system the unit depends on, making that unit less isolated and less subjected to unit testing.&lt;/p&gt;

&lt;p&gt;Whenever you reach out to mock things in a unit test that is a good sign you are in fact writing an integration test. Consider breaking it down into smaller dependency-free pieces and covering them with unit tests. You may then test their integration in the respective testing level.&lt;/p&gt;

&lt;p&gt;In certain cases, mocking has a place in unit tests when those units operate on data that is dependent on runtime, or otherwise hard to predict. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Returns a formatted timestamp string.
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getTimestamp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getHours&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMinutes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSeconds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To unit test the &lt;code&gt;getTimestamp&lt;/code&gt; function reliably we must know the exact date it returns. However, the date has a variable nature and will depend on the date and time when the actual test will run. &lt;/p&gt;

&lt;p&gt;A mock that emulates a specific date during the test would allow us to write an assertion with confidence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;beforeAll&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Mock the timers in Jest to set the system time&lt;/span&gt;
  &lt;span class="c1"&gt;// to an exact date, making its value predictable.&lt;/span&gt;
  &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useFakeTimers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;modern&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setSystemTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;01 Jan 1970 14:32:19 GMT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;afterAll&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Restore to the actual timers and date&lt;/span&gt;
  &lt;span class="c1"&gt;// once the test run is done.&lt;/span&gt;
  &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useRealTimers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;returns the formatted timestamp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getTimestamp&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;14:32:19&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Integration tests
&lt;/h4&gt;

&lt;p&gt;In the integration tests, on the other hand, mocking helps to keep the testing surface focused on the integration of the system's parts, leaving unrelated yet dependent pieces to be fake.&lt;/p&gt;

&lt;p&gt;To illustrate this point, let's consider an integration test of a "Login" component—a form with inputs and a submit button that makes an HTTP call upon form submission.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LoginForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;makeHttpCall&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pasword"&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Log in&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal of an integration test is to ensure that the inputs rendered by the "Login" component are operational (can be interacted with, validated, etc.) and that the login form can be submitted given correct values.&lt;/p&gt;

&lt;p&gt;However, there is a part of our "Login" component's implementation that stretches far beyond the integration of its compounds: the HTTP call. Making an actual request as a part of an integration test would increase its surface to assert two integrations at the same time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integration of the Login form's components;&lt;/li&gt;
&lt;li&gt;Integration of the Login form and some external HTTP server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to keep the testing surface focused on the component itself, we can mock an HTTP request, effectively making it a pre-requisite of the "Login" test. Moreover, with mocks, we can model various HTTP response scenarios, such as a service timeout or failure, and assert how our login form handles them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example of the "Login" component test suite&lt;/span&gt;
&lt;span class="c1"&gt;// written using an abstract testing framework.&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submits the form with correct credentials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Emulate a successful 200 OK response upon form submission.&lt;/span&gt;
  &lt;span class="nf"&gt;mockApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/service/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Logged in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LoginForm&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;fillCredentials&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john.maverick@email.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secret-123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;successfulLoginNotification&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;handles service failure gracefully&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// For this particular test mock a 500 response.&lt;/span&gt;
  &lt;span class="nf"&gt;mockApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/service/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nf"&gt;fillCredentials&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;

  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oopsTryAgainNotification&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  End-to-end tests
&lt;/h4&gt;

&lt;p&gt;End-to-end tests may utilize mocking of external dependencies, like communication with payment providers, as their operability lies beyond your system's responsibilities. &lt;/p&gt;

&lt;p&gt;Mocking any part of the system itself in an end-to-end test contradicts the purpose of this testing level: to ensure the system's functionality as a &lt;em&gt;whole&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It is also plausible to have no mocking at all during end-to-end testing, as that way your system behaves identically to its production version, giving you even more confidence in these tests.&lt;/p&gt;




&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;Thank you for reading! I hope I was able to contribute to your attitude towards mocking and the tips from the article will be useful next time you sit to write a test.&lt;/p&gt;

&lt;p&gt;If you like the material consider &lt;a href="https://twitter.com/kettanaito" rel="noopener noreferrer"&gt;Following me on Twitter&lt;/a&gt; and checking out &lt;a href="https://redd.one" rel="noopener noreferrer"&gt;my personal blog&lt;/a&gt;, where I write about technical and non-technical aspects of software engineering. &lt;/p&gt;

</description>
      <category>testing</category>
      <category>javascript</category>
      <category>mocking</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
