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

javascript - Mock a non-default function using Jest and React - Stack Overflow

programmeradmin2浏览0评论

In a test file I need to render a component while mocking out some of its sub components. The file structure would look loosely something like this.

File 1

import {A, B} from 'a-module';

export function MyComponent() {
    return (
        <div>
            <A /> // I need to mock
            <B /> // these components out
        </div>
    );
}

File 2

import {MyComponent} from 'File 1';

/*
 * In this file I would like to render MyComponent but
 * have components A and B be replaced by mocks
 */

I have tried doing jest.mock('a-module', () => 'Blah'); but this is not successfully mocking the components. This works however when using default imports in File 1.

Any help in mocking out components A and B when rendering MyComponent in file 2 would be most appreciated!

In a test file I need to render a component while mocking out some of its sub components. The file structure would look loosely something like this.

File 1

import {A, B} from 'a-module';

export function MyComponent() {
    return (
        <div>
            <A /> // I need to mock
            <B /> // these components out
        </div>
    );
}

File 2

import {MyComponent} from 'File 1';

/*
 * In this file I would like to render MyComponent but
 * have components A and B be replaced by mocks
 */

I have tried doing jest.mock('a-module', () => 'Blah'); but this is not successfully mocking the components. This works however when using default imports in File 1.

Any help in mocking out components A and B when rendering MyComponent in file 2 would be most appreciated!

Share Improve this question edited Dec 4, 2018 at 15:42 Jordan Epstein asked Dec 3, 2018 at 22:07 Jordan EpsteinJordan Epstein 3174 silver badges15 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 17 +50

You can mock non defaults like this:

jest.mock('a-module', () => ({
  __esModule: true,
  default: () => 'Blah',
  A: () => 'Blah',
  B: () => 'Blah'
}));

https://remarkablemark.org/blog/2018/06/28/jest-mock-default-named-export/

or use __mocks__

as an alternative you could create a file under __mocks__ folder next to the original module with the same name as the module:

a_module_folder > 
    a-module.js
    __mocks__ >
        a-module.js

and that mock should just export the mocked versions:

export const A = () => 'Blah';
export const B = () => 'Blah';

and then just mock like this:

jest.mock('a-module');

for node_modules just put __mocks__folder on the same level as node_modules

https://jestjs.io/docs/en/manual-mocks

Testing React components is mostly done with Enzyme, if you are trying to do it only with Jest you have probably picked the wrong tool. I can only guess why you need to mock a component, but most surely you will be able to achieve it with Enzyme.

There is Enzyme shallow rendering which is specifically created for testing React. Jest itself is not capable of rendering components. The definition as per Airbnb docs is:

Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure that your tests aren't indirectly asserting on behaviour of child components.

Simply said it is going to render the tested component 1 level deep e.g.

// File2.js

import { MyComponent } from 'File1';
import { shallow } from 'enzyme';

describe('MyComponent', () => {
  it('should render shallowly my component', () => {
    const wrapper = shallow(<MyComponent />);
    console.log(wrapper.debug()); 
    // output:
    //   <div>
    //     <A />
    //     <B />
    //   </div>
    // Note: even if component <A /> is consisting of some markup, 
    // it won't be rendered 
  });
});

Essentially you don't need to mock any of its dependent components, these are already mocked with enzyme shallow()

What you can do instead is test when you pass certain props to <MyComponent />, dependent components <A /> and <B /> are receiving expected props.

const wrapper = shallow(<MyComponent foo={1} bar={2} />);
expect(wrapper.find('A').props().foo).toEqual(1);
expect(wrapper.find('B').props().bar).toEqual(2);

If you have a react component which is not default export which is actually a good practice (since default exports should be avoided):

export function MyComponentX() {
    return (
        <div>...</div>
    );
}

You can mock it in jest easily:

jest.mock('path/to/MyComponentX', () => ({
  MyComponentX: () => <>MOCK_MY_COMPONENT_X</>,
}));
发布评论

评论列表(0)

  1. 暂无评论