使用开玩笑的 React 单元测试失败

时间:2021-06-10 11:53:37

标签: reactjs unit-testing react-redux jestjs

我正在用笑话和酶进行单元测试。我有以下带钩子的连接组件。 我调用了 redux 操作来加载数据。

import React, {useEffect, useState, useCallBack} from "react";
import {connect} from "react-redux";
import CustomComponent  from "../Folder";
import { loadData, createData, updateData } from "../../redux/actions";

const AccountComponent = (props) => {
  const total = 50;
  const [aIndex, setAIndex] = useState(1);
  const [arr, setArr] = useState(['ds,dsf']);
 //... some state variables here

const getData = () => {
   props.loadData(aIndex, total, arr);
}

useEffect(() => {

  getData();

},[aIndex, total])

//some other useEffect and useCallback

return(
 <React.Fragment>
   <CustomComponent {...someParam}/>
    <div>
     ...
    </div>
 </React.Fragment>
)

}

const mapStateToProps = (state) => {
 const { param1, param2, parma3 } = state.AccountData;
 return {
  param1,
  param2,
  parma3
 }
}

export default connect(mapStateToProps, { loadData, createData, updateData })(AccountComponent)

在这里,就像下面一样,我为上面的组件创建了一些测试用例。

import AccountComponent from "../";
import React from "react";
import renderer from "react-test-renderer"

describe("AccountComponent component", () => {

 const loadData = jest.fn();
 let wrapper;

 it("snapshot testing", () => {
  const tree = renderer.create(<AccountComponent loadData={loadData} />).toJSON();
  expect(tree).toMatchSnapshot();
 })

  beforeEach(() => {
    wrapper = shallow(<AccountComponent loadData={loadData} />).instance();
  });

  it('should call loadData', () => {
    expect(wrapper.loadData).toHaveBeenCalled();
  });
})

但是,它没有通过并显示错误。

快照测试错误:

<块引用>

不变违反元素类型无效:预期字符串或类/函数

方法调用测试错误:

<块引用>

无法读取未定义的属性“loadData”。

<块引用>

酶内部错误:酶需要配置适配器,但未找到。 ...

不确定是什么问题,因为我不擅长单元测试。

我使用的是 react-redux 7。

任何帮助将不胜感激。

编辑:

我也尝试过像下面这样的提供者。但是,没有帮助。

import { Provider } from "react-redux";
import {createStore} from "redux";
import reducer from "../../reducers";

const store = createStore(reducer);

it("snapshot testing", () => {
      const tree = renderer.create(<Provider store={store}><AccountComponent loadData={loadData} /></Provider>).toJSON();
      expect(tree).toMatchSnapshot();
     })


beforeEach(() => {
        wrapper = shallow(<Provider store={store}><AccountComponent loadData={loadData} /></Provider>).instance();
      });

2 个答案:

答案 0 :(得分:2)

在您的情况下,当您在同一文件中使用连接组件时,您需要通过 public class User { //Other properties.. public List<Post> Posts { get; set; } public List<Comment> Comments { get; set; } } public class Post { //Other properties.. public List<PostComment> Comments { get; set; } [Required] public User CreatedBy { get; set; } } public class Comment { //Other properties.. [Required] public User CreatedBy { get; set; } [Required] public Post Post { get; set; } } public class PostComment { //Other properties.. [Required] public User CreatedBy { get; set; } } 传递状态。此外,您需要配置您的酶。最后,当您使用 react hooks 时,您将需要进行异步单元测试,因为效果是异步的。当你试图检查是否有任何函数被调用时,你需要“窥探”它。

Provider

请使用将在该组件中使用的属性模拟您的 import configureStore from 'redux-mock-store'; import React from 'react'; import renderer from 'react-test-renderer'; import Enzyme, { shallow } from 'enzyme'; import { Provider } from 'react-redux'; import Adapter from 'enzyme-adapter-react-16'; import { act } from 'react-dom/test-utils'; import createSagaMiddleware from 'redux-saga'; import AccountComponent from '../AccountComponent'; import * as actions from '../../../redux/actions'; jest.mock('../../../redux/actions', () => ({ loadData: jest.fn(), createData: jest.fn(), updateData: jest.fn(), })); const loadData = jest.spyOn(actions, 'loadData'); // configure Enzyme Enzyme.configure({ adapter: new Adapter() }); const configureMockStore = configureStore([createSagaMiddleware]); const initialState = { AccountData: { param1: 'param1', param2: 'param2', parma3: 'parma3 ', }, }; const store = configureMockStore(initialState); describe('AccountComponent component', () => { let wrapper; it('snapshot testing', () => { const tree = renderer .create( <Provider store={store}> <AccountComponent /> </Provider>, ) .toJSON(); expect(tree).toMatchSnapshot(); }); beforeEach(async () => { await act(async () => { wrapper = shallow( <Provider store={store}> <AccountComponent /> </Provider>, ); }); await act(async () => { wrapper.update(); }); }); it('should call loadData', () => { expect(loadData).toHaveBeenCalled(); }); }); 状态。另外,我不确定您的测试文件在哪里,因此您可能需要将导入路径从 AccountData 更改为您的操作文件路径。最后,我不确定您使用的是什么中间件,因此请随意将 '../../../redux/actions' 替换为您的 redux 中间件。

答案 1 :(得分:0)

如果您使用的是 react,它已经带有 @testing-library 并且您不需要酶来进行快照测试。这就是我进行快照测试的方式。

  import React, { Suspense } from "react";
  import { screen } from "@testing-library/react";
  import "@testing-library/jest-dom/extend-expect";

  import AccountComponent from "../";

  import store from "./store";// you can mock the store if your prefer too

  describe("<AccountComponent />", () => {
    test("it should match snapshot", async () => {
      expect.assertions(1);
      const { asFragment } = await render(
        <Suspense fallback="Test Loading ...">
          <Provider store={store}>
            <AccountComponent />
          </Provider>
        </Suspense>
      );
      expect(asFragment()).toMatchSnapshot();
    });
  });