使用Jest,RTL,Redux Toolkit,React进行测试的模拟使用应用程序的问题

1sbrub3j  于 9个月前  发布在  Jest
关注(0)|答案(1)|浏览(141)

我已经安装了react redux toolkit,并添加了jest而不是vitest进行测试。
我想测试模态窗口是否呈现在App组件中,如果isOpen标志为true。我只模拟了我需要的部分商店。不是整个商店。
App组件

function App() {
  const { isOpen: isPostModalWindowOpen } = useAppSelector(selectPostModal)

  return (
    <div className="app-container" id="app-container">
      {isPostModalWindowOpen && <PostModalWindow />}
      <Posts />
      <PageLoader />
      <Alert />
    </div>
  )
}

export default App

字符串
测试文件

import App from "../App"
import { PostModalWindow } from "../components/PostModalWindow/PostModalWindow"
import { selectPostModal } from "../redux/postModal"
import { Alert } from "../components/Alert/Alert"
import { PageLoader } from "../components/PageLoader/PageLoader"
import { Posts } from "../components/Posts/Posts"

import { useAppSelector } from "../redux/hooks"
import { render } from "@testing-library/react"
import { RootState } from "../redux/store"
import { clone } from "ramda"

jest.mock("../App", () => ({
  ...jest.requireActual("../App"),
  App: jest.fn(),
}))
jest.mock("../components/PostModalWindow/PostModalWindow", () => ({
  ...jest.requireActual("../components/PostModalWindow/PostModalWindow"),
  PostModalWindow: jest.fn(),
}))
jest.mock("../redux/hooks", () => ({
  ...jest.requireActual("../redux/hooks"),
  useAppSelector: jest.fn(),
}))
jest.mock("../redux/postModal", () => ({
  ...jest.requireActual("../redux/postModal"),
  selectPostModal: jest.fn(),
}))
jest.mock("../components/Alert/Alert", () => ({
  ...jest.requireActual("../components/Alert/Alert"),
  Alert: jest.fn(),
}))
jest.mock("../components/PageLoader/PageLoader", () => ({
  ...jest.requireActual("../components/PageLoader/PageLoader"),
  PageLoader: jest.fn(),
}))
jest.mock("../components/Posts/Posts", () => ({
  ...jest.requireActual("../components/Posts/Posts"),
  Posts: jest.fn(),
}))

describe("Test <App />", () => {
  beforeEach(() => {
    jest.clearAllMocks()

    const initialState = {
      postModal: {
        isOpen: true,
      },
    } as RootState
    let currentState: RootState

    currentState = clone(initialState)

    jest.mocked(useAppSelector).mockImplementation((fn) => fn(currentState))
  })

  it("show modal window if isOpen is true", () => {
    const { container } = render(<App />)
    expect(container).toMatchSnapshot()
  })
})


如何修复此测试错误:TypeError: Cannot destructure property 'isOpen' of '(0 , hooks_1.useAppSelector)(...)' as it is undefined.
我在jest.mocked(useAppSelector).mockImplementation((fn) => fn(currentState))内部console.logged当前状态,它返回postModal: {isOpen: true},所以我不知道为什么它说它是未定义的。

pu82cl6c

pu82cl6c1#

我通过在我的测试方法中发现两个错误来解决这个问题。
首先,我错误地试图模拟App组件。因为我们正在测试App组件本身,所以没有必要模拟它。模拟它会干扰实际测试过程。
其次,我错误地处理了对selectPostModal的模拟。我试图创建一个模拟,而不是提供一个值。

import App from "../App"
import { PostModalWindow } from "../components/PostModalWindow/PostModalWindow"
import { useAppSelector } from "../redux/hooks"
import { Alert } from "../components/Alert/Alert"
import { PageLoader } from "../components/PageLoader/PageLoader"
import { Posts } from "../components/Posts/Posts"

import { render } from "@testing-library/react"
import { RootState } from "../redux/store"
import { clone } from "ramda"

jest.mock("../components/PostModalWindow/PostModalWindow", () => ({
  ...jest.requireActual("../components/PostModalWindow/PostModalWindow"),
  PostModalWindow: jest.fn(),
}))
jest.mock("../redux/hooks", () => ({
  ...jest.requireActual("../redux/hooks"),
  useAppSelector: jest.fn(),
}))
jest.mock("../components/Alert/Alert", () => ({
  ...jest.requireActual("../components/Alert/Alert"),
  Alert: jest.fn(),
}))
jest.mock("../components/PageLoader/PageLoader", () => ({
  ...jest.requireActual("../components/PageLoader/PageLoader"),
  PageLoader: jest.fn(),
}))
jest.mock("../components/Posts/Posts", () => ({
  ...jest.requireActual("../components/Posts/Posts"),
  Posts: jest.fn(),
}))

describe("Test <App />", () => {
  const initialState = {
    postModal: {
      isOpen: true,
    },
  } as RootState
  let currentState: RootState

  beforeEach(() => {
    jest.clearAllMocks()

    currentState = clone(initialState)

    jest.mocked(useAppSelector).mockImplementation((fn) => fn(currentState))
    jest
      .mocked(PostModalWindow)
      .mockImplementation(() => <div>mockedPostModalWindow</div>)
    jest.mocked(Posts).mockImplementation(() => <div>mockedPosts</div>)
    jest
      .mocked(PageLoader)
      .mockImplementation(() => <div>mockedPageLoader</div>)
    jest.mocked(Alert).mockImplementation(() => <div>mockedAlert</div>)
  })

  it("show modal window if isOpen is true", () => {
    const { container } = render(<App />)
    expect(container).toMatchSnapshot()
  })

  it("Don't show modal window if isOpen is false", () => {
    currentState.postModal.isOpen = false

    const { container } = render(<App />)
    expect(container).toMatchSnapshot()
  })
})

字符串

相关问题