单元测试子 React 组件时出错

Posted

技术标签:

【中文标题】单元测试子 React 组件时出错【英文标题】:Error when unit testing child React component 【发布时间】:2021-11-30 15:57:18 【问题描述】:

我有以下 React 组件:

import  getSeasonsalCode  from "./DiscountCodes.js";
import React,  Component  from "react";
import Rating from "./Rating.js";
import ReactDOM from "react-dom";
import "regenerator-runtime/runtime";

class Product extends Component 
  constructor(props) 
    super(props);
    this.handleEvent = this.handleEvent.bind(this);

    this.state = 
      name: "",
      rating: 0,
    ;
  

  setStarCount = (ct) => 
    this.setState( rating: ct );
  ;

  render() 
    var discount = getSeasonsalCode();
    return (
      <div>
        <span>discount</span>
        <Rating
          name="star_rating"
          size="2x"
          setStarCount=this.setStarCount
        ></Rating>
      </div>
    );
  


export default connect(mapStateToProps, null)(Product);

还有下面的product.test.js。它测试 Rating 子组件,这需要父组件的回调函数来设置评级值:

import Rating from "../src/Rating.js";
import Product from "../src/Product.js";
import  shallow, mount  from "enzyme";
import expect from "expect";
import React from "react";
import  Provider  from "react-redux";
import  connect  from "react-redux";
import rootReducer from "../src/reducers/RootReducer.js";
import  createStore  from "redux";

describe("Product test suite", () => 
  it("set rating", () => 
    const store = createStore(
      rootReducer,
      window.__REDUX_DEVTOOLS_EXTENSION__ &&
        window.__REDUX_DEVTOOLS_EXTENSION__()
    );

    const rf_wrapper = mount(
      <Provider store=store>
        <Product />
      </Provider>
    ).dive();
    const rf_instance = rf_wrapper.instance();
    const sr_wrapper = shallow(
      <Rating
        name="star_rating"
        size="2x"
        setStarCount=rf_instance.setStarCount()
      />
    );

    sr_wrapper.find("#star4").simulate("click");
    expect(rf_wrapper.state("starcount")).toEqual(4);
  );
);

当我运行测试时,我得到一个 TypeError 说 discount 在这一行是 null 或 undefined:

<span>discount</span>

是什么导致了这个问题?

【问题讨论】:

getSeasonsalCode 是什么? 为什么不将Rating 组件单独作为一个单元进行单元测试? `getSeasonsalCode` 在测试执行期间做了什么? 修正了错字。 getSeasonsalCode 是顶部导入的外部方法。我确实有一个单独的评级测试套件。在这里,我想测试父母和孩子,因为我想测试一个回调函数(setStarCount)。 啊,我现在明白了,那么您可能不想在测试中额外渲染一个单独的 Rating 组件,找到在 rf_wrapper 中渲染的那个进行交互。 getSeasonsalCode 应该做什么来设置 discountdiscount 是否在其他要求它不为空或未定义的地方使用? React 完全能够呈现这些值中的任何一个。 查找在 rf_wrapper 中呈现的 Rating 组件是有道理的,但不幸的是,在安装 Product 组件时会抛出 null 错误,因此我什至无法访问该实例。 getSeasonsalCode 根据消费者忠诚度积分、季节性等返回折扣代码。产品组件对折扣代码所做的唯一事情就是显示它。 【参考方案1】:

必须对我的原始测试套件进行一些更改,这对我有用:

import * as disc_module from '../src/DiscountCodes.js'

describe("Product test suite", () => 
  it("set rating", () => 
    const store = createStore(
      rootReducer,
      window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    );
    
    var disc_mock_obj = 
        "discount":
            "expiration": new Date()
            "code": "OAABYT"
        

    jest
    .spyOn(disc_module, 'getSeasonsalCode')
    .mockImplementation(() => disc_mock_obj);

    //Got rid of call to dive() since it was not needed
    const rf_wrapper = mount( <Provider store=store><Product></Product></Provider>);
    const prod_inst = rf_wrapper.find('Product');
    
    //Find clickable child component of Rating by id or any other unique attribute
    const child = rf_wrapper.find('#star2')   
    child.simulate('click')     
    expect(prod_inst.state('starcount')).toEqual(2);
  );
);

【讨论】:

以上是关于单元测试子 React 组件时出错的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用主题测试样式化组件时出错

单元测试在测试spring集成TCP组件时创建名为“amqAdmin”的bean时出错

使用 Jasmine 和 Karma 进行角度单元测试时出错

使用带有表单输入元素的 ReactBootstrap 模式对 React 组件进行单元测试

单元测试 React 功能组件的功能

React组件单元测试