{"id":154,"date":"2023-02-06T14:07:32","date_gmt":"2023-02-06T14:07:32","guid":{"rendered":"https:\/\/mrzebra.co.uk\/code\/?p=154"},"modified":"2023-02-06T14:30:19","modified_gmt":"2023-02-06T14:30:19","slug":"how-to-mock-an-http-request-in-nodejs-with-jest","status":"publish","type":"post","link":"https:\/\/zebra-north.com\/code\/2023\/02\/06\/how-to-mock-an-http-request-in-nodejs-with-jest\/","title":{"rendered":"How to Mock an HTTP Request in NodeJS with JEST"},"content":{"rendered":"\n<p>Performing a real HTTP request in a unit test can make it slow and brittle, so the solution is to mock the Node HTTP library.  This guide will show you how to create mock objects that simulate successful and unsuccessful HTTP requests.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Mocking the &#8216;http&#8217;\/&#8217;https&#8217; Library<\/h2>\n\n\n\n<p>If you are using dependency injection and passing the <code>http<\/code> object into your class then this is simple: create a new object and implement the methods you use via JEST&#8217;s <code>jest.fn()<\/code> function.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-javascript\">test(&#039;Test an HTTP request with dependency injection&#039;, async () =&gt; {\n    const http = {\n        get: jest.fn(...),\n    };\n\n    \/\/ Call the function under test and check the expected result.\n    const result = functionUnderTest(http);\n    expect(result).toBe(true);\n}<\/code><\/pre>\n\n\n\n<p>If you are not using dependency injection then you can use <code>jest.mock()<\/code> to override it globally:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-javascript\">test(&#039;Test an HTTP request without dependency injection&#039;, async () =&gt; {\n    const mock = {\n        get: jest.fn(...),\n    };\n\n    jest.mock(&#039;http&#039;, () =&gt; mock);\n\n    \/\/ Call the function under test and check the expected result.\n    const result = functionUnderTest();\n    expect(result).toBe(true);\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Mocking the Request and Response<\/h2>\n\n\n\n<p>When <code>http.get()<\/code> is called it must return an <code>http.Request<\/code> object.  This will then return an <code>http.Response<\/code> object in the <code>response<\/code> event handler.  You must respond to these events by returning mock objects.  These objects should extend <code>EventEmitter<\/code>.  Note that the callback parameter to the <code>http.get()<\/code>function is bound to the <code>request<\/code> event on the request object.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-javascript\">test(&#039;Test an HTTP request with dependency injection&#039;, async () =&gt; {\n    const request = new EventEmitter();\n\n    const http = {\n        get: jest.fn((url, options, callback) =&gt; { request.on(&#039;request&#039;, callback); return request; }),\n    };\n\n    const response = new EventEmitter();\n    response.statusCode = 200;\n\n    \/\/ The response starts by emitting a &#039;request&#039; event.\n    request.emit(&#039;request&#039;, response);\n\n    \/\/ The response body is returned in the &#039;data&#039; event, followed by &#039;end&#039;.\n    response.emit(&#039;data&#039;, &#039;page contents&#039;);\n    response.emit(&#039;end&#039;);\n\n    \/\/ Indicate that no more responses will be sent.\n    request.emit(&#039;close&#039;);\n\n    \/\/ Call the function under test and check the expected result.\n    const result = functionUnderTest(http);\n    expect(result).toBe(true);\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Performing a real HTTP request in a unit test can make it slow and brittle, so the solution is to mock the Node HTTP library. This guide will show you how to create mock objects that simulate successful and unsuccessful HTTP requests.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[23,25],"class_list":["post-154","post","type-post","status-publish","format-standard","hentry","category-nodejs","tag-jest","tag-unit-testing"],"_links":{"self":[{"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/posts\/154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/comments?post=154"}],"version-history":[{"count":5,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/posts\/154\/revisions"}],"predecessor-version":[{"id":160,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/posts\/154\/revisions\/160"}],"wp:attachment":[{"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/media?parent=154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/categories?post=154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zebra-north.com\/code\/wp-json\/wp\/v2\/tags?post=154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}