Test inside function called or not in jest - reactjs

I am writing test cases in jest recently. I have a requirement like should check whether inside function being called or not. Can anyone help me with this?
Here is the code for index.js
componentDidMount() {
this.onSetActionableStateListener = (param) => this.onSetActionableState(param[0]);
client.on('setActionableState', this.onSetActionableStateListener);
}
I am writing code in index.test.js like this
it('should call onSetActionableState in componentDidMount', () => {
wrapper.instance().componentDidMount();
// const onSetActionableState = jest.fn();
expect(wrapper.instance().onSetActionableState).toBeCalled();
});
I want to test whether onSetActionableState is called or not?

Related

Is it possible to mock functions outside of the test file for multiple tests to use?

Thanks in advance
Issue
I have some functions that need to be mocked in every test file. However, only in some of those files, do I actually care to evaluate or test those mock functions.
For example, let's say, that when my app renders, it immediately fetches some data In A.test.tsx I want to mock that fetch and verify that it was called.
But, in B.test.tsx, I still need to mock that fetch, but I don't care to verify that it was called.
Goal
I would like the setup to look something like this:
setup.ts
import * as SomeAPI from 'api';
const setup = () => {
jest.spyOn(SomeAPI, 'fetchData');
return { SomeAPI };
};
export default setup;
A.test.tsx
const { SomeAPI } = setup();
beforeEach(() => {
jest.clearAllMocks();
});
test('data should be fetched when app renders', async () => {
RenderWithProviders(<App />);
expect(SomeAPI.fetchData).toHaveBeenCalled();
});
B.test.tsx
setup(); // Don't destructure because I don't care to test the mock
beforeEach(() => {
jest.clearAllMocks();
});
test('test some other stuff', async () => {
// In this case, the fetchData still needs to be mocked<br>
// because the rest of the app depends on it
RenderWithProviders(<App />);
expect(someElement).toBeInTheDocument();
});
My Current Problem
My problem is that while I'm trying to attempt this way of returning mocked functions... If that mocked function is used more than once in the same test file, the jest.clearAllMocks() seems not to have an effect. I assume because the setup is happening outside of the test?
Is this possible to setup mocks outside of the test and only destructure them when needed?

Jest Test Failed - TypeError: window.matchMedia is not a function

I try to make a snapshot testing using react-test-renderer, I need to render a component which use the code below (in a separate file) to conditionally render different component.
let mql = window.matchMedia("(max-width: 600px)");
let mobileView = mql.matches;
export default mobileView;
This is the snapshot test
test("Your test case", () => {
const component = renderer.create(<CalendarTitle month={8} year={2021} />);
let tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
I have tried using jest-matchmedia-mock package but it can't solve the problem, maybe it need to mock in a different file but i am not sure what to write in matchMedia.mock.ts file and what is the myMethod from "file-to-test" and how to write to complete test method.
import matchMedia from './matchMedia.mock.ts'; // Must be imported before the tested file
import { myMethod } from './file-to-test';
describe('myMethod()', () => {
// Test the method here...
});

How to test internal functions using react hooks testing library?

I have a custom hook that I am trying to write tests for using the react hooks testing library package and I would like to know how I can test internal functions that are not returned in the custom hook but are used within other functions.
const customHook = () => {
const [count, setCount] = React.useState(0);
const doSomeThing = () => {
..code
}
const increment = () => {
doSomeThing(); //Would like to make assertations on this
setCount((x) => x + 1 );
}
return { count, increment }
}
export default customHook;
test
it('Should call increment', () => {
const { result } = renderHook(() => useCustomHook())
act(() => {
result.current.increment();
});
expect(doSomeThing).toHaveBeenCalled(); //end result of what I would like help on
});
How can I write a test to see if doSomething has been called/used?
You can't. It's entirely internal to that hook, and no handle is provided to get at that function. So you can't mock it, and you can't call it directly. It's impossible to test only the doSomething function as you have it.
And more to the point, you shouldn't. You don't want to test at that level. This is a private implementation detail. You should test the public interface of your hook. That means test the arguments, the return values, and how calling functions the hook returns affect the next returned values.
Tests shouldn't care how a function does its job. Tests should only care that the function does its job correctly.
That means your test can only verify what doSomething does, and not whether it's been called. And as of right now, it doesn't do anything at all, so there's nothing to test.

Jest testing that a React class method was called by componentWillMount

I am trying to write a test to assert that my class method is being called when the componentWillMount method fires when the component renders.
I have tried the Jest documentation in addition to researching this online. From the answers I've found (including on here) there seemed to be 2 possible methods of doing this.
The first was to:
shallow render the component
create a jest.fn of the class method I want to test,
call componentWillMount using wrapper.instance().componentWIllMount
assert that the method was called once
The second was to spy on the method I'm expecting to be called:
shallow render the component
set up the spy and assign to a constant e.g. functionSpy
call componentWillMount
assert the functionSpy was called how ever many times
The refresh method definitely fires whenever the component is rendered so I just need to work out how I can reflect this in a test.
The code base I am working on is for a civil service system so have to be really careful what I disclose, hopefully this will be enough for explaining the problem I'm having..
The class is structured:
export class Search extends AnErrorComponent {
static propTypes = {
.....
};
state = {
.....
}
componentWillMount(){
this.refresh();
}
refresh = () => {
.....
} // This is the method I'm trying to test
but can't seem to access/test.
search = () => {
.....
}
//etc
render(){
return(
...
);
}
}
To test this I've tried:
describe('Search component', () => {
it("should call the refresh method when the page loads", () => {
const store = makeStore();
const wrapper = shallow(<Search store={store}/>);
wrapper.instance().refresh = jest.fn();
wrapper.update();
wrapper.instance().componentWillMount;
expect(wrapper.instance().refresh).toHaveBeenCalledTimes(1);
});
});
The result of running this test is:
● Search component › should call the refresh method when the page loads
expect(jest.fn()).toHaveBeenCalledTimes(1)
Expected mock function to have been called one time, but it was called zero times.
I also tried:
describe('Search component', () => {
it("should call the refresh method when the page loads", () => {
const store = makeStore();
const wrapper = shallow(<Search store={store}/>);
const refreshSpy = spyOn(Search.prototype, 'refresh');
wrapper.instance().componentWillMount;
expect(refreshSpy).toHaveBeenCalledTimes(1);
});
});
I get the error:
● Search component › should call the refresh method when the page loads
refresh() method does not exist
This refers to the spy I tried to create.
I've double checked and I have imported the Search component in addition to the component it inherits from. I have also tried using mount instead of shallow rendering; however to make this work I had to wrap the component in a provider otherwise an error would be thrown e.g.
<provider store={store}>
<Search />
</provider>
I still got the same results after when using mount and wrapping the component in a provider. Due to the spy error I tried console logging wrapper.instance() in both tests and noted that none of the class methods are listed anywhere if this helps? Any help on this would be greatly appreciated. (This is the first question I've posted on here so hopefully this makes sense).
** Just to add, when using jest.spyOn() I get TypeError: jest.spyOn is not a function. I am using Jest 21.2.1 which I read should allow me to use jest.spyOn() as it was added in V19. **
componentWillMount is a method on the class instance, not a property. You need to call it to trigger the effect:
describe('Search component', () => {
it("should call the refresh method when the page loads", () => {
const store = makeStore();
const wrapper = shallow(<Search store={store}/>);
wrapper.instance().refresh = jest.fn();
wrapper.update();
wrapper.instance().componentWillMount(); // Calling the method
expect(wrapper.instance().refresh).toHaveBeenCalledTimes(1);
});
});
You need to call componentWillMount and spyOn the refresh function by Mock Implementation
describe('Search component', () => {
const store = makeStore();
const wrapper = shallow(<Search store={store}/>);
let refresh;
beforeAll(() => {
refresh = jest.spyOn(Search.prototype, 'refresh').mockImplementation(() => true);
});
it("should call the refresh method when the page loads", () => {
wrapper.instance().componentWillMount();
expect(refresh.mock.calls.length).toBe(1);
});
afterAll(() => {
refresh.mockRestore();
});
});

Jest - Mock Nested Function

I am writing a JEST/Enzyme test case for module.
One of the function I am testing in my component is about saving an xml file. Which in turn calls a library function fileDownload from 'react-file-download'
const saveContentToXML = () => {
if(this.props.message && this.props.message.details){
fileDownload(this.props.message.details, this.props.message.title);
}
}
When I wrote test case, it calls saveContentToXML and in turn calls fileDownload. This results in exception.
TypeError: window.URL.createObjectURL is not a function
My test case looks like
test('Save Content as XML Test', () =>{
const component = shallow(<Message details={details} />);
component.instance().saveContentToXML();
});
How do I test this function?
You should mock react-file-download and then assert that it is being called
// Default mock will just make fileDownload a jest mock function
jest.mock('react-file-download')
import fileDownload from 'react-file-download'
test('Save Content as XML Test', () =>{
const component = shallow(<Message details={details} />);
component.instance().saveContentToXML();
expect(fileDownload).toHaveBeenCalledWith('details', 'title');
fileDownload.mockClear() // resets the mock function so the call is not used in assertions for other tests
});
The jest documentation on mock functions is a good resource to refer to: https://facebook.github.io/jest/docs/mock-functions.html

Resources