javascript - Jest Mock React 组件仅在某些测试中

标签 javascript reactjs unit-testing jestjs react-testing-library

这个问题真的很好: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>
  `)
})

关于javascript - Jest Mock React 组件仅在某些测试中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63410262/

相关文章:

scala - 使用Spark数据框进行单元测试

javascript - html - 为什么单选按钮被多次选择而不是一个单选框?

javascript - 在 React 中,如何根据传入的 props 动态渲染组件?

reactjs - React 使用 TypeScript,不要使用 {} 作为类型。 {

java - 为什么 mock 对象的 getter() 返回 null?

java - 如何模拟 System.in?

javascript - 字符串以 html 标签开头

javascript - Bug 修复被遗弃的 Firefox 附加组件、Wikilook?

c# - 将按钮移动到 Div

javascript - Anime.js 动画与 React 的高阶组件