使用Jest监视componentDidMount中的方法调用

时间:2017-04-06 03:16:11

标签: javascript reactjs testing jestjs enzyme

我最近想测试一些自定义方法是否在React组件的componentDidMount方法中有条件地调用。

componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}

我正在使用Jest作为我的测试框架,其中包括jest.fn()用于模拟/间谍。我已经读过,通过做类似以下的事情,用Sinon测试这将是相当微不足道的:

sinon.spy(Component.prototype, "methodName");
const wrapper = mount(<Component {...props} />);
expect(wrapper.instance().methodName).toHaveBeenCalled();

我正试图用Jest重新创建这个:

Component.prototype.methodName = jest.fn();
const wrapper = mount(<Component {...props} />);
expect(wrapper.instance().methodName).toHaveBeenCalled();

此代码失败并引发以下错误:

jest.fn() value must be a mock function or spy.
Received:
  function: [Function bound mockConstructor]

是否可以使用Jest测试此功能?如果是这样,怎么样?

4 个答案:

答案 0 :(得分:53)

关键是使用jests @FeignClient(name = "SEARCHCABMS", url = "${SEARCHCABMS.service.url}", configuration = ClientConfiguration.class) public interface SearchCabMsClient { } 方法。它应该是这样的:

spyOn

如此处所示,例如:Test if function is called react and enzyme

请注意,最佳做法是在每次测试运行后清除间谍功能

const spy = jest.spyOn(Component.prototype, 'methodName');
const wrapper = mount(<Component {...props} />);
wrapper.instance().methodName();
expect(spy).toHaveBeenCalled();

https://facebook.github.io/jest/docs/en/jest-object.html#jestclearallmocks

答案 1 :(得分:13)

我知道它有点晚了,但我遇到了这个并建议测试componentDidMount启动对嵌套方法的调用,你的测试看起来应该是这样的:

<强>模块

componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}

测试 - 好

it('should call methodName during componentDidMount', () => {
    const methodNameFake = jest.spyOn(MyComponent.prototype, 'methodName');
    const wrapper = mount(<MyComponent {...props} />);
    expect(methodNameFake).toHaveBeenCalledTimes(1);
});

如果您致电componentDidMount,那么通过methodName调用componentDidMount的断言更有效。

测试 - 错误

it('should call methodName during componentDidMount', () => {
    const spy = jest.spyOn(Component.prototype, 'methodName');
    const wrapper = mount(<Component {...props} />);
    wrapper.instance().methodName();
    expect(spy).toHaveBeenCalled();
}

通过这样编写测试 - 您调用该方法然后断言它被调用。当然它会让你刚刚调用它。

答案 2 :(得分:0)

如果您要测试在public上调用的componentDidMount方法(如果使用的是TypeScript),则需要显式调用instance的{​​{ 1}}方法调用,因为直到实例化组件之后才定义公共方法。

要测试以下内容:

代码

componentDidMount

测试

public componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}

public methodName = () => {
  // some code here
}

答案 3 :(得分:0)

class AllInOneSer(serializers.Serializer):
    data = serializers.JSONField()

    def to_internal_value(self, data):
        return {"data": data}

    def validate(self, attrs):
        print("->>>--------------> validate: ")

        type, errors = self.all_data_check_or_save(data=attrs["data"], flag=0)
        if type == "error":
            raise ValidationError(errors)
        return attrs

    def create(self, validated_data):
        print("->>>--------------> save: ")
        type, errors = self.all_data_check_or_save(data=validated_data["data"], flag=1)
        return errors


    def all_data_check_or_save(self, data, flag=0):

        errors = {}
        status = "success"
        app_no = data["app_no"]
        
        if flag:
            basic_details = dict(data["applicant_basic_details"], **{"applicant": app_no})
            family_datails = dict(data["applicant_family_datails"], **{"applicant": app_no})

        basic_details = data["applicant_basic_details"]
        family_datails = data["applicant_family_datails"]

        app_ser = ApplicantSer(data={"app_no": app_no})
        status1, errors["app_data"] = self.validation_or_save_res(app_ser, flag)

        basic_ser = ApplicantBasicDetailsSer(data=basic_details)
        status2, errors["applicant_basic_details"] = self.validation_or_save_res(basic_ser, flag)

        family_ser = AppplcantFamilyDetailsSer(data=family_datails)
        status3, errors["applicant_family_datails"] = self.validation_or_save_res(family_ser, flag)

        if "error" in [status1, status2, status3]:
            status = "error"

        return status, errors  


    def validation_or_save_res(self, serializer, flag=0):
        if serializer.is_valid():
            if flag:
                serializer.save()
        else:
            return "error", serializer.errors, extra_data

        return "success", {}