Using Jest functions as object properties results in undefined behavior

I am faced with a challenge in my class where I need to mock an object along with its properties

intercept(context: ExecutionContext) {
  const response = contect.switchToHttp().getResponse() // the chain that needs to be mocked

  if (response.headersSent) { // testing this scenario
    return true
  }

  return false
}

When I simulate the dependency using a regular object literal and some anonymous functions, everything runs smoothly as anticipated

const executionContext = {
  switchToHttp: () => executionContext, // simulates 'this' chaining
  getRequest: () => {
    return {
      url: undefined,
      method: undefined,
      headers: undefined,
      connection: {
        remoteAddress: undefined,
        remotePort: undefined
      }
    }
  },
  getResponse: () => {
    return {
      headersSent: true, // desire an easy way to alter this during testing without resorting to a factory
      append: () => undefined
    }
  }
} as unknown as ExecutionContext

it('test', () => {
  const response = myclass.intercept(executionContext);

  expect(response).toBeTrue()
});

However, when I attempt to mimic some of the properties using jest.fn(), unexpected outcomes surface.

const getResponseSpy = jest.fn(() => {
  return {
    headersSent: false,
    append: () => undefined
  }
});

const executionContext = {
  switchToHttp: () => executionContext,
  getRequest: () => {
    return {
      url: undefined,
      method: undefined,
      headers: undefined,
      connection: {
        remoteAddress: undefined,
        remotePort: undefined
      }
    }
  },
  getResponse: getResponseSpy // provides a more convenient way to modify this 
} as unknown as ExecutionContext

At this stage in my code, the response turns out to be undefined

TypeError: Cannot read property 'headersSent' of undefined

Moreover, if I try something like

getResponse: () => getResponseSpy
, then the response within my code becomes a Jest mock object instead of the mimicked implementation, lacking the headersSent property.

I sense that I might be overlooking a fundamental aspect. I attempted utilizing

switchToHttp: jest.fn().mockResturnThis()

Nevertheless, no alterations occur. It appears that the jest spy inside the object fails to provide its simulated implementation

What could be the issue here?

Answer №1

Using mockFn.mockReturnThis() is essential.

For example:

app.js:

interface UserContext {
  switchToHttp(): UserContext;
  getResponse(): UserContext;
  headersSent: boolean;
}

export const myModule = {
  intercept(context: UserContext) {
    const response = context.switchToHttp().getResponse();

    if (response.headersSent) {
      return true;
    }

    return false;
  },
};

app.test.js:

import { myModule } from './';

describe('87654321', () => {
  it('should succeed', () => {
    const userContext = {
      switchToHttp: jest.fn().mockReturnThis(),
      getResponse: jest.fn().mockReturnThis(),
      headersSent: true,
    };
    const result = myModule.intercept(userContext);
    expect(result).toBeTruthy();
  });
});

Test outcome:

 PASS  examples/87654321/app.test.js (8.387 s)
  87654321
    ✓ should succeed (3 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |      80 |       50 |     100 |      80 |                   
 app.js   |      80 |       50 |     100 |      80 | 15                
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.273 s

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Create a dropdown menu with selectable options using a b-form-select

I am working with a b-form-select element that displays options based on user input. I am trying to figure out how to trigger a function when the user selects one of the dynamically generated <b-form-option> elements, but I am struggling to capture b ...

Effectively encoding and decoding AJAX and JSON objects with PHP scripting

I've successfully set up a basic HTML file with a fixed JSON object. My goal is to transfer this object to a PHP file named text.php, encode it, decode it, display it in the PHP file, and then showcase it back in the HTML file. <!DOCTYPE html> ...

Having trouble initiating an AJAX call in Django and returning values to my form

Seeking assistance to run an AJAX call for a quick calculation in my django view and display the result within a span tag on my HTML page. New to Javascript, struggling with triggering my AJAX call. Below is my HTML and JS code: <input type="text" nam ...

Issue with npm during installation of REACT - not functioning as expected

After executing all the necessary commands on the command line, including globally installing npm with npm install -g create-react-app, as well as running npx create-react-app <myprojectname> and clearing the npm cache, I consistently encountered an ...

Angular 7+: Trouble with displaying images from assets directory

Details regarding my Angular version: Angular CLI: 7.3.9 Node: 10.15.3 OS: win32 x64 Angular: 7.2.15 ... animations, common, compiler, compiler-cli, core, forms ... language-service, platform-browser, platform-browser-dynamic ... rout ...

What is the best way to run an npm script with grunt-run?

I currently have a npm task specified in my package.json file for running jest tests: "scripts": { "test-jest": "jest", "jest-coverage": "jest --coverage" }, "jest": { "testEnvironment": "jsdom" }, I would like to run this task using ...

Deleting data from Firebase in Angular can be easily done using the AngularFire library. By

I am attempting to remove specific values from my Firebase database. I need to delete this entry from Firebase: https://i.stack.imgur.com/CAUHX.png So far, I have tried using a button to trigger the delete function like this: <div class="single-bfunc ...

In what scenario should I respond with true or false to AJAX, and when is it more appropriate to use the echo function to output "true" or "false

It seems I have managed to confuse myself. I mistakenly believed that when using AJAX to communicate with PHP (like $.post), one had to echo back a "true" or "false" instead of simply returning true or false. I now realize this is not the case, but could ...

What is the process of incorporating a lowercase normalizer into an Elasticsearch mapping object?

I'm attempting to incorporate a normalizer with a lowercase option into my mapping object, as detailed in the official Elasticsearch documentation Below is an example of my mapping object: const schema = { date: { type: 'date' ...

Converting a Javascript object to JSON format only once using AngularJS

Is it possible to convert a JavaScript object to JSON using angular.toJson only once in my code? Here is an example: $scope.task.tags = [{"id":22,"tag":"printer","created_at":"2016-03-15" }]; $scope.create = function(task) { tmp.tags = angular.toJson( ...

Having trouble mocking useAppSelector in Jest, RTL, Redux Toolkit, and React testing

I have react redux toolkit installed and have replaced vitest with jest for testing purposes. My goal is to test whether the modal window is rendered in the App component when the isOpen flag is true. I only mock the part of the store that is necessary, n ...

The output of the http.get or http.request callback is only visible within the shell when using node.js

Just dipping my toes into node and aiming to avoid falling into the callback hell trap. I'm currently working with two files: routes.js fetch.js //routes.js var fetchController = require("../lib/mtl_fetcher/fetcher_controller"); var express = requir ...

After an ajax call in ASP .NET MVC3 using Razor, jQuery may not function properly

When I perform a post back to obtain a partial view using ajax, I utilize the following code to render the partial view within a div named 'DivSearchGrid'. <script type ="text/javascript" > $('#Retrieve').click(function ( ...

Adding an additional element to an object - crossroads of combining types versus sequential examination

Here's a query for you: AppendToObject. When I first tackled this question, my initial instinct was to utilize type intersection like so: type AppendToObject<T, U extends PropertyKey, V> = T & {[P in U]: V} Unfortunately, this solution did ...

How come I'm not receiving an error message when I enter an incorrect email or password?

Whenever I try to log in with the wrong password and email, no error message is displayed. Instead, it simply logs me in and takes me to the main page. Can someone please assist me in implementing an error message display for incorrect login details? imp ...

Troubleshooting a Missing Angular (8) Pipe Error in Your Ionic 4 Application

Despite seeing similar questions posted here, none have provided a solution to my issue. I believe I am implementing it correctly, but clearly something is not right. In the app I'm developing with Ionic 4, I need to add a key to a URL in a gallery. ...

The integration of express and cors() is malfunctioning

Currently, I am developing a React application and facing an issue while trying to make an API call to https://itunes.apple.com/search?term=jack+johnson In my project, there is a helper file named requestHelper.js with the following content : import &apo ...

Issue with passing parameter values in MVC Html.ActionLink

Currently, I am experimenting with MVC for a demonstration and have managed to put together some components. However, I am encountering difficulties with an Html.ActionLink. The goal is to display a series of dropdown lists to the user that must be selecte ...

Implementing Ajax to Load Template-Part in Wordpress

Hey there! I'm currently working on enhancing my online store by adding a new feature. What I'd like to achieve is that when a customer clicks on a product, instead of being taken to the product page, the product details load using AJAX right on ...

Issue with Ajax reload functions malfunctioning

Embarking on a new journey, I am diving headfirst into the world of web development. As an artist and writer, I have recently delved into the realm of creating a project that integrates a cms, project manager, and database front-end using php, mysql, and j ...