最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Mock useSelector with different values - Stack Overflow

programmeradmin0浏览0评论

I'm trying something like this:

const useSelector = jest.fn();
jest.mock('react-redux', () => ({
  useSelector,
}));

Then trying to do something like this:

useSelector.mockReturnValueOnce({});
shallow(
  <ComponentUsingUseSelector />
);

That will give me an error:

The module factory of jest.mock() is not allowed to reference any out-of-scope variables.

So if I can't use an out of scope variable for a mock then how would I return a different value for every test?

I'm trying something like this:

const useSelector = jest.fn();
jest.mock('react-redux', () => ({
  useSelector,
}));

Then trying to do something like this:

useSelector.mockReturnValueOnce({});
shallow(
  <ComponentUsingUseSelector />
);

That will give me an error:

The module factory of jest.mock() is not allowed to reference any out-of-scope variables.

So if I can't use an out of scope variable for a mock then how would I return a different value for every test?

Share Improve this question edited Apr 18, 2020 at 18:34 skyboyer 23.7k7 gold badges61 silver badges71 bronze badges asked Apr 18, 2020 at 14:43 HMRHMR 39.3k25 gold badges98 silver badges173 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 6

Simplified version, which also works:

import * as redux from 'react-redux'

jest
  .spyOn(redux, 'useSelector')
  .mockReturnValueOnce('first call')

Also, instead of relying on multiple calls to mockReturnValueOnce it's better to just stub the necessary part of the store:

const locale = 'en'

const state = {
  application: { locale },
}

jest
  .spyOn(redux, 'useSelector')
  .mockImplementation((callback) => callback(state))

The following seems to work, after reading tons of articles and documentation that does not do what I (think) need to do; finally found one that does.

import { useSelector } from 'react-redux';

jest.mock('react-redux', () => ({
  useSelector: jest.fn(),
}));


describe('some test', () => {
  it('do something', () => {
    useSelector.mockImplementation(() => ('hello world'));
    shallow(
      <ComponentUsingUseSelector />
    );

If it's called multiple times I can do:

describe('some test', () => {
  it('do something', () => {
    useSelector.
      .mockReturnValueOnce('first call')
      .mockReturnValueOnce('second call')
    shallow(
      <ComponentUsingUseSelector />
    );

Update answer to versions react-redux v8

Cannot redefine property: useSelector issue

If you're getting the following error:

  TypeError: Cannot redefine property: useSelector
        at Function.defineProperty (<anonymous>)

Apply this before tests:

import * as Redux from 'react-redux';

jest.mock('react-redux', () => ({
    ...jest.requireActual('react-redux'),
    useSelector: jest.fn()
}));

Example:

import * as Redux from 'react-redux';

// This will enable to mock readonly
jest.mock('react-redux', () => ({
    ...jest.requireActual('react-redux'),
    useSelector: jest.fn()
}));

describe('Component Tests', () => {
    beforeEach(() => {
        jest.spyOn(Redux, 'useSelector').mockReturnValue({
            users: [] // your mock here
        });
       // or
       // (useSelector as jest.Mock).mockImplementation(() => ({
       //      useSelector:[] your mock
       // }));
    });
    test('should render component', () => {
        render(<MyComponent />);
    });
});
发布评论

评论列表(0)

  1. 暂无评论