Sunday, June 2, 2024
 Popular · Latest · Hot · Upcoming
143
rated 0 times [  145] [ 2]  / answers: 1 / hits: 17049  / 3 Years ago, fri, may 14, 2021, 12:00:00

I'm trying to unit test a function that returns a promise. I'm having challenges verifying if
the mocked functions are called. Here's what I've done.,


// codetotest.js
const { SomeModule, isSomething, isSomethingElse } = require("some-module");

exports.somefunction = (param1, param2)=> {
const someModule = new SomeModule();

someModule.someMethod("aaa", isSomething);
someModule.someMethod("bbb", isSomethingElse);

return (someModule.someOtherMethod(param1)
.then(()=>{someModule.run(param2)}));
}

And this is the test file, the test says the mocked functions are not called, but I do see the console statement in the mock function is being displayed.


// codetotest.test.js
const { somefunction} = require("./codetotest.js");
const { SomeModule } = require("some-module");

jest.mock("some-module", () => {
return {
SomeModule: jest.fn().mockImplementation(() => {
return {
someMethod: jest.fn((param, fn) => { console.log("This prints!"); }),
someOtherMethod: jest.fn((param) => { return Promise.resolve(() => { }) }),
run: jest.fn((param) => { return Promise.resolve(() => { return []; }) })
}
})
};
});

afterEach(() => {
jest.resetAllMocks();
jest.restoreAllMocks();
});

describe("Test codetotest.js", () => {
it("somefunction() - success", async () => {
const someModule = new SomeModule();

let output = await somefunction("param1", "param2");

expect(SomeModule).toHaveBeenCalled();
expect(someModule.someMethod).toHaveBeenCalled(); // This fails

await expect(someModule.someOtherMethod.mock.results[0]).resolves;
expect(someModule.someOtherMethod).toHaveBeenCalled(); // This fails

await expect(someModule.run.mocks.results[0]).resolves;
expect(someModule.run).toHaveBeenCalled(); // This fails
});
});

Appreciate any help/pointers.


Thank you.


P.S: I'm still a beginner when it comes to nodeJs development and unit testing.


More From » node.js

 Answers
24

I spent quite some time on this and finally figured the instantiated mock class didn't return the mocked methods properly. This answer gave me a hint on where I was going wrong.


So accordingly, I had to change my test file as follows.,


// codetotest.test.js
const { somefunction} = require("./codetotest.js");
const { SomeModule } = require("some-module");

jest.mock("some-module", function() {
return {
SomeModule: jest.fn().mockImplementation(function() { // Arrow function cannot be used as constructor
// Because I was not using the 'this' operator, my constructor always returned empty
this.someMethod = jest.fn((param, fn) => { console.log("This prints!"); });
this.someOtherMethod = jest.fn((param) => { return Promise.resolve(() => { }) });
this.run = jest.fn((param) => { return Promise.resolve(() => { return []; }) });
return {
someMethod: this,someMethod,
someOtherMethod: this.someOtherMethod,
run: this.run
}
})
};
});

afterEach(() => {
jest.restoreAllMocks();
});

describe("Test codetotest.js", () => {
it("somefunction() - success", async () => {
await somefunction("param1", "param2");

expect(SomeModule).toHaveBeenCalled();
expect(SomeModule.mock.instances[0].someMethod).toHaveBeenCalled(); // This works
expect(SomeModule.mock.instances[0].someOtherMethod).toHaveBeenCalled(); // This works
expect(someModule.mock.instances[0].run).toHaveBeenCalled(); // This works
});
});

[#50288] Wednesday, April 14, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
susanajamiep

Total Points: 466
Total Questions: 113
Total Answers: 108

Location: Liberia
Member since Fri, Oct 22, 2021
3 Years ago
susanajamiep questions
Sun, Jun 12, 22, 00:00, 2 Years ago
Mon, Mar 7, 22, 00:00, 2 Years ago
Wed, Jun 10, 20, 00:00, 4 Years ago
Fri, Jan 24, 20, 00:00, 4 Years ago
;