簡體   English   中英

如何解析useEffect中的act()?

[英]How to resolve act() in useEffect?

我在 react-testing-library 中遇到 act() 錯誤的小問題。 在 useEffect 中,我嘗試調用一個 function,它是一個 promise。Promise 返回一些數據並顯示它,但即使測試通過,仍然顯示行為錯誤。 成分:

export function getUser() {
  return Promise.resolve({ name: "Json" });
}

const Foo = () => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    const loadUser = async () => {
      const userData = await getUser();
      setUser(userData);
    };
    loadUser();
  }, []);

  return (
    <div>
      <p>foo</p>
      {user ? <p>User is: {user.name}</p> : <p>nothing</p>}
    </div>
  );
};

我的 Foo 組件也在 App Component 中,就像這樣:

import Foo from "./components/Foo";

function App() {
  return (
    <div>
      some value
      <Foo />
    </div>
  );
}

export default App;

測試:

  test("should display userName", async () => {
    render(<Foo />);
    expect(screen.queryByText(/User is:/i)).toBeNull();
    expect(await screen.findByText(/User is: JSON/i)).toBeInTheDocument();
  });

你有什么想法來解決它嗎?

編輯:這是一條錯誤消息

console.error
    Warning: An update to Foo 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 */

waitFor act讓渲染解析。

import { render, waitFor } from '@testing-library/react-native';
import { useEffect, useState } from 'react';
import { Text } from 'react-native';

describe('useState', () => {
  it('useState', () => {
    function MyComponent() {
      const [foo] = useState('foo');
      return <Text testID="asdf">{foo}</Text>;
    }
    const { getByTestId } = render(<MyComponent></MyComponent>)
    expect(getByTestId("asdf").props.children).toBe("foo");
  });
  it('useState called async', async () => {
    function MyComponent() {
      const [foo, setFoo] = useState('foo');
      useEffect(() => {
        (async () => {
          setFoo(await Promise.resolve('bar'))
        })()
      }, []);
      return <Text testID="asdf">{foo}</Text>;
    }
    const {getByTestId} = await waitFor(()=>render(<MyComponent></MyComponent>))
    expect(getByTestId("asdf").props.children).toBe("bar");
  });
});

除了上述針對更新不會立即發生的情況(即超時)的答案之外,您還可以使用await act(()=>Promise.resolve()); (請注意,由於輸入不當,這會生成警告,但需要await才能工作。

這是一個renderHook的例子

  it("should return undefined", async () => {
    const { result } = renderHook(() => {
      const [loaded, loadedFonts] = useExpoFonts([]);
      return useReplaceWithNativeFontCallback(loaded, loadedFonts);
    }, {});


    const replaceWithNativeFont0 = result.current;
    expect(replaceWithNativeFont0({})).toBeUndefined();
    await act(() => Promise.resolve());
    const replaceWithNativeFont1 = result.current;
    expect(replaceWithNativeFont1({})).toBeUndefined();
  });

典型的render

  it("should render fonts", async () => {
    function MyComponent() {
      const [loaded, loadedFonts] = useExpoFonts([]);
      const replaceWithNativeFont = useReplaceWithNativeFontCallback(
        loaded,
        loadedFonts
      );
      const style = replaceWithNativeFont({
        fontFamily: "something",
        fontWeight: "300",
      });
      return <View testID="blah" style={style} />;
    }
    const { unmount } = render(
      <ThemeProvider>
        <MyComponent />
      </ThemeProvider>
    );


    await act(() => Promise.resolve());
    expect(screen.getByTestId("blah").props.style).toStrictEqual({
      fontFamily: "something",
      fontWeight: "300",
    });
    unmount();
  });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM