首页 > 解决方案 > React State 在断言之前没有得到更新,即使在 act 函数中起作用

问题描述

为什么下面的单元测试用例失败了?我在现实世界中也有类似的情况,但在这里,我正在测试它的简化版本。

我期望断言应该在行为完成钩子的状态更新后执行,但它的行为不是那样的。尽管状态正在更新,但在断言执行之后。

请建议是否有其他方法可以测试这种情况。

代码

 const HookForTest = () => {
  const [data, setData] = useState('');

  const updateDataFromOutside = toData => {
    setData(toData);
  };

  return [data, updateDataFromOutside];
};

单元测试

describe('HookForTest', () => {
  test('should change state on calling updateDataFromOutside function ', async () => {
    let hookData;

    testHook(() => {
      hookData = HookForTest();
    });

    let [data, updateDataFromOutside] = hookData;

    await act(async () => {
      updateDataFromOutside('testData');
    });

    expect(data).toEqual('testData');
  });
});

我正在使用一些实用程序函数来测试自定义钩子,下面是代码:

export const TestHook = ({callback}) => {
  callback();
  return null;
};

export const testHook = callback => {
  mount(<TestHook callback={callback} />);
};

测试结果


 ● HookForTest › should change state on calling updateDataFromOutside function 

    expect(received).toEqual(expected) // deep equality

    Expected: "testData"
    Received: ""

      178 |     });
      179 | 
    > 180 |     expect(data).toEqual('testData');

标签: reactjsjestjsreact-hooks

解决方案


这里的问题是let [data, updateDataFromOutside] = hookData;将 的值锁定data为其原始值。即使hookData[0] = 'something else'调用了类似的东西, 的值data仍然是''

将测试更改为这样的东西应该可以

describe('HookForTest', () => {
  test('should change state on calling updateDataFromOutside function ', async () => {
    let data;
    let updateDataFromOutside;

    testHook(() => {
      let hookData = HookForTest();
      data = hookData[0]
      updateDataFromOutside = hookData[1]
    });

    await act(async () => {
      updateDataFromOutside('testData');
    });

    expect(data).toEqual('testData');
  });
});

推荐阅读