在使用React Native和Hooks的Jest测试期间状态没有更新

时间:2019-05-29 04:40:42

标签: reactjs react-native jestjs enzyme react-hooks

我正在尝试测试组件中的功能,基本思想是设置了某种状态,并且当按下按钮时,会以设置状态调用功能。该代码有效,但是当我尝试对此进行测试时,没有得到预期的结果,就好像在测试期间从未设置状态一样。

我正在使用Jest和Enzyme测试的React Native应用程序中使用带有挂钩(useState)的功能组件。

一个重复我的问题的例子是:

import React, { useState } from "react";
import { View, Button } from "react-native";
import { shallow } from "enzyme";

const Example = function({ button2Press }) {
const [name, setName] = useState("");

  return (
    <View>
      <Button title="Button 1" onPress={() => setName("Hello")} />
      <Button title="Button 2" onPress={() => button2Press(name)} />
    </View>
  );
};

describe("Example", () => {
  it("updates the state", () => {
    const button2Press = jest.fn();
    const wrapper = shallow(<Example button2Press={button2Press} />)
    const button1 = wrapper.findWhere(node => node.prop("title") === "Button 1")
                        .first();
    const button2 = wrapper.findWhere(node => node.prop("title") === "Button 2")
                        .first();

    button1.props().onPress();
    button2.props().onPress();

    expect(button2Press).toHaveBeenCalledWith("Hello");
  });
});

任何对我做错事/失踪的帮助都会很棒。

1 个答案:

答案 0 :(得分:0)

这里的问题是两件事。首先,在执行操作将导致状态更新后,我需要调用wrapper.update();。其次,我需要在执行wrapper.update();后再次找到该元素,以使该元素具有更新的状态。

有效的解决方案是:

import React, { useState } from "react";
import { View, Button } from "react-native";
import { shallow } from "enzyme";

const Example = function({ button2Press }) {
const [name, setName] = useState("");

  return (
    <View>
      <Button title="Button 1" onPress={() => setName("Hello")} />
      <Button title="Button 2" onPress={() => button2Press(name)} />
    </View>
  );
};

describe("Example", () => {
  it("updates the state", () => {
    const button2Press = jest.fn();
    const wrapper = shallow(<Example button2Press={button2Press} />)
    const button1 = wrapper.findWhere(node => node.prop("title") === "Button 1")
                        .first();
    button1.props().onPress();
    wrapper.update(); // <-- Make sure to update after changing the state

    const button2 = wrapper.findWhere(node => node.prop("title") === "Button 2")
                        .first(); // <-- Find the next element again after performing update
    button2.props().onPress();

    expect(button2Press).toHaveBeenCalledWith("Hello");
  });
});