简体   繁体   English

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

[英]Jest Mock React Component ONLY in some tests

This question is really good: Jest Mock module per test这个问题真的很好: Jest Mock module per test

It just don't answer my question on how to only mock it out in one single test and keep the rest using the original component.它只是没有回答我关于如何仅在一次测试中模拟它并使用原始组件保持 rest 的问题。

That would make sense if I wish to do some mocking for an snapshot but not for the other tests如果我想为快照做一些 mocking 而不是其他测试,那将是有道理的

This is my current attempt这是我目前的尝试

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>
  `)
})

This is the component to test这是要测试的组件

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(...) the component you want to mock in one of tests. jest.mock(...) 您要在其中一项测试中模拟的组件。

Use jest.requireActual(...) to implement default behavior.使用 jest.requireActual(...) 来实现默认行为。

Use mockImplementation to implement custom behavior.使用 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>
  `)
})

I don't have the permission to add comments so I will just leave this here.我没有添加评论的权限,所以我将把它留在这里。

I have tried the solution offered by Han Daniels and I was getting the error:我尝试了 Han Daniels 提供的解决方案,但出现错误:

TypeError: specificMockImpl.apply is not a function . TypeError: specificMockImpl.apply is not a function

I have fixed it by adding .default after jest.requireActual('components/Photo') because Photo is the default export.我已经通过在jest.requireActual('components/Photo')之后添加.default来修复它,因为 Photo 是默认导出。

So it is: jest.requireActual('components/Photo').default所以它是: jest.requireActual('components/Photo').default

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM