I have a mock as follows
jest.mock('react-hook-inview', () => {
const setRef = jest.fn();
const observer = jest.fn();
const intersecting = true;
const entry = {
y: 0,
};
return [setRef, intersecting, entry, observer];
});
Here I would like to change the intersecting
value. How can I change that from one test to another? I was trying to use something like a factory:
const inView = (intersecting) => {
jest.mock('react-hook-inview', () => {
const setRef = jest.fn();
const observer = jest.fn();
const entry = {
y: 0,
};
return [setRef, intersecting, entry, observer];
});
}
and use it like
it('is invisible by default', () => {
const text = 'Test';
const { container } = render(<Reveal>{text}</Reveal>);
inView(false);
expect(container.firstChild).not.toBeVisible();
});
it('is visible when in view', () => {
const text = 'Test';
const { container } = render(<Reveal>{text}</Reveal>);
inView(true);
expect(container.firstChild).toBeVisible();
});
however this throws
The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: intersecting
does anybody have an idea?
cheers!
My solution for now is to mock it like this
import ReactHookInview from 'react-hook-inview';
jest.mock('react-hook-inview', () => ({
useInView: jest.fn().mockImplementation(() => {
const setRef = jest.fn();
const observer = jest.fn();
const intersecting = false;
const entry = {
boundingClientRect: {
y: 0,
},
};
return [setRef, intersecting, entry, observer];
}),
}));
and in my test I overwrite like this:
ReactHookInview.useInView.mockImplementation(() => {
const setRef = jest.fn();
const observer = jest.fn();
const intersecting = true;
const entry = {
boundingClientRect: {
y: 1,
},
};
return [setRef, intersecting, entry, observer];
});
but that's not really beautiful
The Jest library provides the jest. fn() function for creating a “mock” function. An optional implementation function may be passed to jest. fn() to define the mock function's behavior and return value.
In Jest, Node. js modules are automatically mocked in your tests when you place the mock files in a __mocks__ folder that's next to the node_modules folder. For example, if you a file called __mock__/fs. js , then every time the fs module is called in your test, Jest will automatically use the mocks.
You can create a namespace that you export as the default object and call b using the namespace. This way, when you call jest. mock it will replace the b function on the namespace object. const f = require('./f'); jest.
You can mock your library as you have already done, import it and explicitly set it's value. And then before have two different sets of tests:
jest.mock('react-hook-inview', /* as above */ );
import rhi from 'react-hook-inview';
describe('my implementation', () => {
describe('while intersecting', () => {
let result;
beforeAll(() => {
rhi[1] = true;
result = myImplementationUsingIntersecting();
});
it('should result X', () => {
expect(result).toEqual(X);
});
});
describe('while NOT intersecting', () => {
let result;
beforeAll(() => {
rhi[1] = false;
result = myImplementationUsingIntersecting();
});
it.todo('should result Y');
});
})
working example
Edit 2: in order to properly mock a React hook
since the react hooks are functions that return stuff you'll can mock it like this
jest.mock('react-hook-inview', () => jest.fn());
// and you can take it's reference with import
import useInView from 'react-hook-inview';
// and then you can mock it's return value as array
beforeAll(() => {
useInView.mockReturnValue(['a', true, 'b', 'c']);
result = myImplementationUsingIntersecting();
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With