how do i get a jest/enzyme test to pass this requi

2019-08-20 07:50发布

问题:

Hi I'm trying to test a react module that contains the code <img alt='avatar' src={require(`../../assets/${avatar}`)} /> which concats a path and a prop containing a file name received from the redux store. It renders fine but the test throws the error "Cannot find module '../../assets/' from 'UserProfile.js'" which sounds like it thinks the path is a module. The full code is as follows:

The module

import React from 'react'
import PropTypes from 'prop-types'

const UserProfile = ({name='', avatar=''}) => {

    return (
        <section className='bg-bright padding-m'>
            <img alt='avatar' src={require(`../../assets/${avatar}`)} />
            {name}
        </section>
    )

}

UserProfile.propTypes = {
    name: PropTypes.string,
    avatar: PropTypes.string
}

export default UserProfile

The test

import { shallow } from 'enzyme'
import UserProfile from '../../../src/components/ui/UserProfile'

describe('<UserProfile /> component', () => {
    it('renders enclosing html tag', () => 
        expect(
            shallow(<UserProfile />)
                .find('section')
                .length
            ).toBe(1)
        )
})

The redux store data it's using looks something like

{
    "name": "a name",
    "avatar": "name.jpg"
  }

The error

● <UserProfile /> component › renders enclosing html tag

    Cannot find module '../../assets/' from 'UserProfile.js'

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:179:17)
      at Object.UserProfile [as type] (src/components/ui/UserProfile.js:8:72)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:104:34)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:289:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:93:16)

The line in question renders as

<img alt="avatar" src="/static/media/admin.34e378b0.jpg">

If anyone has any insights it'd be appreciated. If the insights involve a better way to return the image path that would be fine too. Thanks.

回答1:

First of all you need to pass some props when shallow rendering your component:

describe('<UserProfile /> component', () => {
    it('renders enclosing html tag', () => 
        expect(
            shallow(<UserProfile name="fakeName" avatar="fakeAvatar" />)
                .find('section')
                .length
        ).toBe(1);
    );
});

Then after that enzyme will look for a module at the path ../../assets/${avatar} so in the case of the test above: ../../assets/fakeAvatar

There is obviously nothing at that path so you need to mock it:

jest.mock('../../assets/fakeAvatar', () => 'fake/image/url.png');

So your full test would be

describe('<UserProfile /> component', () => {
    it('renders enclosing html tag', () => 
        jest.mock('../../assets/fakeAvatar', () => 'fake/image/url.png');
        expect(
            shallow(<UserProfile name="fakeName" avatar="fakeAvatar" />)
                .find('section')
                .length
        ).toBe(1);
    );
});