How to mock unit functions using Jest in react - reactjs

I have below code in my render method
render() {
let isNew = Boolean(domService.getQueryParamByName("isNew"));
if(isNew) {
return(
// soemthing
)} else {
return(// return anything)
Now how to mock the getQueryParamByName unit function in the jestUnit testcase such that it should cover if block.

If you are importing the domService from another file to your component, inside the test you can add a spy like this:
//component.test.js
import domService from "relative-path";
const mockFunction = jest.fn((obj) => {});
beforeEach(() => {
mockFunction.mockClear();
jest.spyOn(domService,"getQueryParamByName").mockReturnValue(mockFunction);
});

Related

How do I mock a function being used by my React Component in Jest testing?

So I have something like the following:
function calculate = (value) => { return value + somecalculations }
class MyComponent extends React.Component {
...
render() {
if (calcuate(this.props.value) === 1) {
return(<MyComponentVersion1 />)
} else {
return <MyComponentVersion2 />
}
}
}
My question is, when doing jest unit testing, I want to be able to mock the function calculate(). But the function is global to that file, and is not part of my react component. Is there a way to mock this function so it always returns say 1? Thanks
If you want to do this without any extra dependencies (like a mocking library), you should be able to use dependency injection by telling MyComponent which function to use by setting it in a prop on your component to achieve this, like so:
calculate = (value) => { return value + somecalculations }
class MyComponent extends React.Component {
constructor(props) {
this.calculate = this.props.calculate || calculate
}
render() {
if (this.calculate(this.props.value) === 1 {
return (<MyComponentVersion1 />)
} else {
return (<MyComponentVersion2 />)
}
}
}
...and then, in your test, you can use a mock-calculate function:
test('put a really good test description here', () => {
const mockCalculate = () => 1
const myTestSubject = (<MyComponent calculate={mockCalculate} value={whatever}/>)
// the rest of your test
})
If you want to use an actual mocking library instead, maybe try sinon.js Mocks.
You need a way to access the calculate function from outside of the file. The easiest way to do this would be to export the function separately:
export function calculate () {
// ...
}
This option is also minimally invasive to your source code.

How do I mock a react component property in jest which is instance of another class?

I want to test a react component which has instance of a service as a property. This service's method is called by a method in the component. I want to mock the service so its implementation is not my concern. Following is excerpts of my requirement:
// Component
export class SomeComponent extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
someService - new SomeService(arg1, arg2)
handleClick() {
// some transformations
this.someService.someMethod()
}
render() {
return <Button onClick={this.handleClick}>
</Button>
}
}
// test
describe.only('<SomeComponent/>', () => {
it.only('should call handleClick when button is clicked', () => {
const wrapper = shallow(<SomeComponent/>) // shallow render from enzyme
const handleClick = jest.fn()
const instance = wrapper.instance()
instance.handleClick = handleClick
wrapper.find(Button).simulate('click')
expect(handleClick).toHaveBeenCalledTimes(1)
})
})
But now I get the implementation details error of the services. How can I mock the service so that I can simply test the method of my Component?
If your project is a webpack project, then https://github.com/plasticine/inject-loader is very useful. You can simply swap any dependency with a mock in just a few lines of code.
describe('SomeComponent', () => {
let SomeComponent;
let SomeServiceSpy;
beforeEach(() => {
SomeServiceSpy= // {a mock/spy};
SomeComponent= require('inject-loader!./SomeComponent')({
'../services/SomeService': {SomeServiceSpy},
});
});
it('should ...', () => {
const wrapper = shallow(<SomeComponent/>)
wrapper.find(Button).simulate('click')
expect(SomeServiceSpy).toHaveBeenCalledTimes(1)
});
});
Note: make sure you don't import the module under test (SomeComponent) at the top of your file. The require call does that part.

How to mock dependency being used in my React component?

I have something akin to the following case:
import { someFunction } from "./utils/function"
class ExampleComponent extends React.Component {
buildPages = () => {
return someFunction();
}
render() {
const pages = this.buildPages();
return <div className="container">{pages}</div>;
}
}
My code is a lot more complicated than the above, but the above is what it boils down to.
I have the following test:
describe("ExampleComponent", () => {
it("should match snapshot", () => {
// Somehow mock someFunction being used in the component.
expect(mount(getExampleComponent())).toMatchSnapshot();
};
});
someFunction is an expensive computation, and I basically want it to just be a jest.fn().mockReturnValue(true) when testing. Is there a way to do this? I read up on mocking with jest, but none of them seem to go over this use case. I'm not interested in passing someFunction in as a prop.
Turns out it is as simple as this:
import * as Functions from "./utils/function";
describe("ExampleComponent", () => {
it("should match snapshot", () => {
jest.spyOn(Functions, "someFunction").mockImplementation(() => {
return true
})
expect(mount(getExampleComponent())).toMatchSnapshot();
};
});
The import * as Functions from "./utils/function"; is pretty important stylistically, as the jest.spyOn takes two parameters, and you need the function you're spying on as the second parameter string.

How do I test that a function is called within a method using jest+enzyme+react+typescript?

Say I have this method in my react component
handleSubmit(){
if (this.state.fireRedirect === false){
this.setState({ fireRedirect: true }, () => { this.addEndpoint() });
}
}
How do I test that addEndpoint was called using Jest and Enzyme?
Use jest.spyOn
const spy = jest.spyOn(Component.prototype, "addEndPoint");
const wrapper = shallow(<Component/>);
expect(spy).not.toHaveBeenCalled();
wrapper.instance().handleSubmit();
expect(spy).toHaveBeenCalled();

How to spy on refs in React?

I have a component that has a MapView from react-native-maps. I want to test that I'm calling MapView.fitToSuppliedMarkers() inside componentDidUpdate of my component.
I'm using enzyme and jest for testing.
My code under test:
componentDidUpdate() {
//some other code
this.refs.map.fitToSuppliedMarkers(/* some parameters */);
}
But I struggle on how to access and spy on this.refs using enzyme and jest.
The problem was I relied on deprecated string refs which didn't allow for testing. Once, I upgraded to callback refs I was able to spy on refs using the prototype object.
code under test
componentDidUpdate() {
//some other code
this.map.fitToSuppliedMarkers(/* some parameters */);
}
render() {
return (
<MapView
ref={(map) => { this.map = map; }}
>
</MapView>
);
}
the unit test
it('zooms in on markers when receiving new data', () => {
Map.prototype.map = {
fitToSuppliedMarkers: function () { }
};
const spy = spyOn(Map.prototype.map, 'fitToSuppliedMarkers');
const testee = shallow(
<Map markers={[]} />
);
const withAnimation = true;
testee.setProps({ markers: markers });
expect(spy).toHaveBeenCalledWith(markers, withAnimation);
});

Resources