I write a test for a method:
const methods = {
run: (name) => {
console.log('run');
return name;
}
}
Using const testMethod = jest.spyOn(methods, 'run').mockResolvedValue({});, the console.log('run') is not triggered, but if i write: const testMethod = jest.spyOn(methods, 'run');, the console.log() is triggered. Why in the first case the console.log() is not triggered and how to solve this?
When you use mockResolvedValue, you are replacing your function with a stub. As the purpose of a stub is not to execute the real implementation of the function but just to return a fictitious value, this behavior is normal.
jest.fn().mockResolvedValue({})
is equivalent to:
jest.fn().mockImplementation(() => Promise.resolve({}));
https://jestjs.io/docs/mock-function-api#mockfnmockresolvedvaluevalue
Update:
If you want to verify if your function is called and if it returned a specific value, then:
const spy = jest.spyOn(methods, 'run');
const myName = 'John Doe';
// Call the method...
expect(spy).toBeCalled();
expect(spy).toHaveReturnedWith(myName);
Related
I am stuck on this for few days now.
while testing my handler function I would like to "fake" the call to rotateApiKeys fonction I was thinking to use stubs to achieve that.
But first I would like to see if at least I could spy on rotateApiKeys while calling the handler, so far I am getting:
AssertError: expected rotateApiKeys to be called once but was called 0 times and I can see that function actually been called.
Questions:
What would you recommend me to use? Mock/Stub/Spy
If Spy should work, why I am getting that assertError?
Handler:
async function handler(event) {
// declare a new JSON object
let handlerObject = {
"event": event,
"isValidEvent": rotateFunctions.validateEvent(event),
"actionCountObject": {}
};
if (handlerObject.isValidEvent) {
// continue here
handlerObject.actionCountObject = await rotateApiKeys(event);
}
// console log JSON handlerObject
console.log("handlerObject: " + JSON.stringify(handlerObject));
// return the object
return handlerObject;
}
unit test code:
it("Should call rotate", async function() {
var rotate = sinon.spy(rotateApiKeys, 'rotateApiKeys');
const result = await rotateApiKeys.handler(event);
rotate.restore();
sinon.assert.calledOnce(rotate);
});
I'm creating my own package that needs to do some emitting from the package to the main file.
This simplified module gets what I'm trying to achieve:
const fetch = require("node-fetch")
module.exports.client = async function(username,password,version) {
// Do login code here
this.emit("login", loginData)
}
Then my test code runs that with
var client = new require("../index").client("username","password","0.774")
client.on("login",function(data) {
console.log(data)
})
With every time, the program returning
client.on("login",function(data) {
^
TypeError: client.on is not a function
Has anyone had a similar issue? This is my first time making a module in this style, so please let me know.
Thank you!
Because your function client() exported from index.js is declared with the async keyword, it will return a Promise rather than an actual value passed to the return statement. Assuming the value you return from the function client() is an object with an on() function, then in order to access this function you either need to await the result of client() or you need to use the .then() function on promise. Example:
var clientPromise = new require("../index").client("username","password","0.774")
clientPromise.then(client => {
client.on("login",function(data) {
console.log(data)
})
});
While you could also use await on the result of the client() function, this is not allowed in all contexts, and so you would have to wrap the code that does this in another async function.
I have function which I would like to fake using sinon. I inject faked function using DI.
Usually I do
fake.resolves(result) but I cannot change resolved value during test.
I execute function three times and I expect different result each time. I would like to do something like here fake.resolvesEach([result1, result2, result3]).
What could I use to solve my problem?
You should use onCall(n) function
Sample 1:
const FetchStub = sinon
.stub()
.onCall(0)
.resolves(serviceAccountAccessTokenRes)
.onCall(1)
.resolves(signJsonClaimRes)
.onCall(2)
.resolves(getTokenRes)
.onCall(3)
.resolves(makeIapPostRequestRes);
const sample = getSample(FetchStub);
Sample 2:
describe("stub", function () {
it("should behave differently on consecutive calls", function () {
const callback = sinon.stub();
callback.onCall(0).returns(1);
callback.onCall(1).returns(2);
callback.returns(3);
assert.equals(callback(), 1); // Returns 1
assert.equals(callback(), 2); // Returns 2
assert.equals(callback(), 3); // All following calls return 3
});
});
You can read documents in https://sinonjs.org/releases/latest/stubs/
How can we do callback on success and failue cases for below lines of code for test coverage using jest
const handleService = () => {
window.domain.service("1321",'',onSuccess, onFailure)
}
const onSuccess = () => {
....update state values
}
const onFailure = () => {
....update state values
}
Something like this:
Spy on window.domain.service to gain access to the calls it receives. This will allow you to access the parameters of those calls which will be "1321",'',onSuccess, onFailure
Assign the function you wish to test to a variable
Invoke the function to execute the code in it (this will get you the coverage)
(Optional) assert that the callback functions behave correctly
Here is a snippet to help demonstrate
it('should run', () => {
// Some setup to create the function on the window, may not be needed if done elsewhere.
// Could be good to do this in a beforeEach and clean up in afterEach to avoid contaminating the window object
window.domain = {
service: () => {},
}
// Spy on the window.domain.service method.
// Provide a mock implementation if you don't want the real one to be called
const serviceSpy = jest.spyOn(window.domain, 'service');
executeYourCode();
// capture the arguments to the call
const [_arg1, _arg2, onSuccess, onFailure] = serviceSpy.mock.calls[0];
// execute the callbacks
onSuccess();
onFailure();
});
Example: I have an NPM module that I import:
const ex = require('ex');
And I use it in a bunch of different places:
const response1 = await ex.doThis()
const response2 = await ex.doThat()
At the end of each function, I also want to log a specific part of the response for all methods in ex. Is there a way to 'override' doThis and doThat (and all other functions) such that that I can simply log something after the function is done running without having to manually add a log every time I call those functions?
I'm thinking about making a wrapper over ex and re-exporting it, but I'm not sure how to modify the functions so that first they run themselves as is and then run my custom log function from the response they return. Thanks for the help!
This will override all the methods of a package and execute console.log('DONE'); after the method execution is done. You'll have a little more work to do to handle promises, but that shouldn't be an issue.
const path = require('path');
function override(module) {
Object.getOwnPropertyNames(module).forEach((property) => {
if (typeof module[property] === 'function') {
const method = module[property];
module[property] = function () {
// You need to handle promises here
const res = method.apply(module, arguments);
console.log('DONE'); // Replace this with your logging function
return res;
};
}
});
}
override(path);
console.log(path.extname('https://www.google.com'));