开玩笑地测试以更新被拒绝的承诺中的反应状态

testing with jest to update a react state inside a rejected promise

这是 this question 的延续。我做了一些更改来简化问题(我相信)并彻底改变它。

我已经分开创建挂钩和初始化 MIDI 事件。

describe("midiConnection", () => {
    it("Should fail", () => {
        const midiPorts = renderHook(() => { return MidiConnection()})
        act(() => {
            midiPorts.result.current.enable()
        })
        console.log(midiPorts.result.current.error)
    })
})
export function MidiConnection() {
    const {array: midiInputs, push: midiPush, filter: midiFilter} = useArray(["none"])
    const [error, setError] = useState<Error | undefined>();
    function enable() {
        WebMidi.addListener("connected", (e) => { if (isInput(e)) {midiPush(e.port.name)}});
        WebMidi.addListener("disconnected", (e) => {
            e.port.removeListener()
            if (isInput(e)) {midiFilter((str) => {return str != e.port.name})}
        });
        // setError("this is a test")
        WebMidi.
        enable().
        catch((err) => {
            // console.log("test")
            // setError(err)
        })
    }
    return ({ports: midiInputs, error, enable})
}

警告依旧;

Warning: An update to TestComponent inside a test was not wrapped in act(...).
    
    When testing, code that causes React state updates should be wrapped into act(...):
    
    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */

除了分离出一些逻辑之外,我还尝试将 setError() 放在其他行上,看看是否可以触发警告(注释掉的注释。)

似乎只有当我尝试更新来自 enable() 的承诺被拒绝时的状态时才会触发警告。

我能做些什么来阻止这个错误的发生?

编辑:我在 CodeSandbox 中创建了这个的工作副本,如果你去测试并查看控制台,你会看到它。

您的挂钩是异步的,因此您需要等待下一次更新。 Here is the docs that talks more about it.

import { renderHook, act } from "@testing-library/react-hooks/dom";
import CHook from "./../hook/CHook";

test("This is a test", async () => {
  const { result, waitForNextUpdate } = renderHook(() => CHook());
  act(() => {
    result.current.update();
  });
  await waitForNextUpdate();
  console.log(result.current.error);
});

Here is the link to a fixed sandbox.