React Jest - Mock a function with callback - reactjs

I'm trying to write a test for following code
var throttle = require('lodash.throttle');
search = throttle(async (searchTerm:string) => {
const response = await AxiosWrapper.Instance.post(this.props.url, { "searchTerm": searchTerm });
this.setState({
searchResult: response.data as ISearchResult,
showSearchResult: true
});
},500);
So, my mock looks like
jest.mock("lodash.throttle", () => {
console.log("blah");
});
I would like to execute callback from throttle func.

If you look at the jest docs for jest.mock, the second argument is a factory (function) that returns the mock value for the module. In this case, we are mocking the lodash.throttle function, so we want a factory that returns a function. If you want to mock lodash.throttle such that it just calls the callback that is passed in, you would do
jest.mock("lodash.throttle", () => cb => cb())

Related

jest spyOn mockimplementation on callback as argument not working

Here I'm trying to mock a function whose args is a callback function which setState inside. but I'm not able to cover this piece of code in code coverage.
Is this the right way to mock this function?
const func =()={
//some other logic
window.__promos.holiday.event('gift',(data)=>{
setState(data)
})
}
test('window.__promo calls the callback function with the correct data', () => {
// Spy on the callback function and provide a mock implementation
jest.spyOn(window.__promo.holiday, 'event').mockImplementation(('gift', cb) => {
cb('data');
});
});

Jest - how to mock a class in jest

I've been trying to mock a test in jest through the methods that they have on their documentation. By mocking the whole class but I can't seem to get it to work properly.
https://jestjs.io/docs/en/es6-class-mocks
jest.mock('../../../../../src/SubscriptionOrder');
SubscriptionOrder.prototype.createChargebeeSubscription = jest.fn(() => 'response');
const test = new SubscriptionOrder(
'subscription',
[{}],
'errorMethods',
'customerMethods',
);
test.createChargebeeSubscription();
I'd expect this to mock the createChargebeeSubscription method and return the string response but it seems to be returning undeifined
Then this is the piece of code I'm trying to run a test for as well.
const subscriptionOrder = new SubscriptionOrder(
'subscription',
subscriptionRequest,
errorMethods,
customerMethods,
);
const response = await subscriptionOrder.createChargebeeSubscription(token);
this.setState({ successfulSubmit: response });
I want to update the state to the string response but getting undefined instead. so it appears I'm kinda mocking something but just not properly.
You can use spyOn as follows to do the mocking for you. I also recommend that you set up and tear down this spy once you are finished.
So here's a sample piece of code which will do what you want:
describe('createChargebeeSubscription() method behaviour', () => {
let createChargebeeSubscriptionSpy;
let testResponse;
beforeAll(() => {
// Lets create an instance of your class first
const subscriptionOrder = new SubscriptionOrder(
'subscription',
subscriptionRequest,
errorMethods,
customerMethods
);
// Now use a spy to mock the return value from your function
createChargebeeSubscriptionSpy = jest.spyOn(subscriptionOrder, 'createChargebeeSubscription').mockImplementation(() => {
return 'response';
});
// Finally invoke the method being tested
testResponse = subscriptionOrder.createChargebeeSubscription();
});
afterAll(() => {
// Restore the functionality (ie. disable the spy) of your method
createChargebeeSubscriptionSpy.mockRestore();
});
it('verifies that the expected response was returned', () => {
expect(testResponse).toBe('response');
});
});

Trying to spyOn a mocked function

I am trying to perform a spyOn on a function that exists in a mocked class:
test.ts -
import Service from '../base_classes/Service';
jest.mock('../base_classes/Service');
const o: Component = new Component();
it('should load model specific information', async () => {
const getSpy = jest.spyOn(Service.prototype, 'get');
let t = await o.load(1);
expect(t.name).toEqual('test_name');
expect(getSpy).toHaveBeenCalledTimes(1);
});
__mocks__/Service.ts -
export const mockGet = jest.fn(async () => Promise.resolve({name:
'test_name'}));
const mock = jest.fn().mockImplementation(() => {
return {
get: mockGet
}
});
export default mock;
The resulting error is: Cannot spy the get property because it is not a function
I tried changing the mocked arrow function to a function(), but that didn't help.
How can I set this up so I can spy on my mocked function?
When using jest.mock it automatically creates a mock for each property of the module, replacing it's functions with jest.fn() (without implementation). And from then on you can write assertions. There should be no reason you'd want to spy on a mock function as it's already a mock function.
You should either spy on the actual implementation or write assertions for the methods on the mocked module.
e.g.
it('should load model specific information', async () => {
let t = await o.load(1);
expect(t.name).toEqual('test_name');
expect(Service.mock.instances[0].get).toHaveBeenCalledTimes(1);
});
working example

Jest mock a function within object

Trying the following :
// Function Spies
const onSubmitSpy = jest.fn().mockName('onSubmitSpy');
const onHistoryPushSpy = jest.fn().mockName('onPushSpy');
// Default Props
const defaultProps = {
signupUserMutation: onSubmitSpy,
history: {
push: onHistoryPushSpy
}
};
Then within my test this spy gets called withing my code like this
history.push('/');
(I verified with mock Response) but the call count in test response always remains 0.
I have a feeling this is maybe because this is a nested object I am missing something ?
test('should submit and call routing change', () => {
...
expect(onHistoryPushSpy).toHaveBeenCalledTimes(1);
});
And I always get this error
Expected mock function to have been called one time, but it was called zero times.

How can we test the return type of method by using sinon.spy?

We are using the sinon to test our api call in reactjs application Like this:-
import * as Actions from 'routes/actions/Actions';
const requestAction = {
RequestShell() { Actions.request(); },
};
describe('testing for Actions', () => {
it('check whether request() method call is happening properly or not', () => {
const requestData = sinon.spy(requestAction, 'RequestShell');
requestAction.RequestShell();
sinon.assert.calledOnce(requestData);
requestData.restore();
});
Now I need to compare if Actions.request() return type is Json object or not. How can I test the return type of the action by using sinon? Please assist me.
Try with this
JS
it('check whether request() method call is happening properly or not', () => {
const requestData = sinon.spy(requestAction, 'RequestShell');
requestAction.RequestShell();
assert(requestData.calledOnce);
requestAction.RequestShell.restore();
});
refer this linksinon spies

Resources