问题描述
这个问题真的很好:Jest Mock module per test
这只是不回答我的问题,即如何仅在一个测试中对其进行模拟,而其余的仍使用原始组件。
如果我想为快照做一些模拟而不是其他测试,那将很有意义
这是我目前的尝试
import React from 'react'
import { render } from '@testing-library/react'
jest.mock('components/Photo',() =>
jest.fn(() => jest.requireActual('components/Photo'))
)
import Photo from 'components/Photo'
import PhotoGrid from '.'
beforeEach(() => {
Photo.mockReset()
})
test('default renders 9 photos if provided 9',() => {
const photos = [...Array(9).keys()]
const { getAllByTestId,debug } = render(<PhotoGrid photos={photos} />)
debug()
expect(getAllByTestId(PHOTO_COMP_TEST_ID)).toHaveLength(9)
})
test('renders with masonry grid style',() => {
Photo.mockImplementation(() => <div />)
const photos = [...Array(9).keys()]
const { container,debug } = render(<PhotoGrid photos={photos} />)
debug()
expect(container).toMatchInlineSnapshot(`
<div>
...
</div>
`)
})
这是要测试的组件
import React from 'react'
import Masonry from 'react-masonry-css'
import './index.css'
import Photo from 'components/Photo'
function PhotoGrid({ photos,numberOfPhotos = 9 }) {
const imgs = photos ? photos.slice(0,numberOfPhotos) : []
const breakpointColumnsObj = {
default: 4,1300: 3,900: 2,700: 1,}
return (
<Masonry
breakpointCols={breakpointColumnsObj}
className="my-masonry-grid"
columnClassName="my-masonry-grid_column"
>
{imgs &&
imgs.map(({ id,secret,server,farm },index) => (
<div key={index} className="masonry-item">
<Photo id={id} secret={secret} server={server} farm={farm} />
</div>
))}
</Masonry>
)
}
export default PhotoGrid
解决方法
jest.mock(...) 您想在其中一个测试中模拟的组件。
使用 jest.requireActual(...) 实现默认行为。
使用 mockImplementation 实现自定义行为。
import React from 'react'
import { render } from '@testing-library/react'
jest.mock('components/Photo')
import Photo from 'components/Photo'
import PhotoGrid from '.'
// This maintains the original implementation for tests.
// This step is important because if not done,it will
// result in empty render errors.
beforeEach(() => {
Photo.mockImplementation(jest.requireActual('components/Photo'));
})
// This test will use original implementation of 'components/Photo'
test('default renders 9 photos if provided 9',() => {
const photos = [...Array(9).keys()]
const { getAllByTestId,debug } = render(<PhotoGrid photos={photos} />)
debug()
expect(getAllByTestId(PHOTO_COMP_TEST_ID)).toHaveLength(9)
})
// This test will use the mocked implementation of 'components/Photo'
test('renders with masonry grid style',() => {
Photo.mockImplementation(() => <div />)
const photos = [...Array(9).keys()]
const { container,debug } = render(<PhotoGrid photos={photos} />)
debug()
expect(container).toMatchInlineSnapshot(`
<div>
...
</div>
`)
})