Reputation: 379
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
Upvotes: 7
Views: 14363
Reputation: 32158
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');
});
})
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();
})
Upvotes: 2