Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 使用React和Enzyme测试异步处理程序中的中间状态_Reactjs_Jestjs_Enzyme_Assert - Fatal编程技术网

Reactjs 使用React和Enzyme测试异步处理程序中的中间状态

Reactjs 使用React和Enzyme测试异步处理程序中的中间状态,reactjs,jestjs,enzyme,assert,Reactjs,Jestjs,Enzyme,Assert,尽管阅读了和的文档,但我找不到对我的用例的响应,因为示例只显示了简单的用例 我有一个显示按钮的React组件。onClick处理程序设置加载布尔值并调用外部API。我想断言,当我们单击按钮时,组件显示加载指示器 以下是组件: export default function MyButton(): ReactElement { const [loading, setLoading] = useState<boolean>(false); const [data, set

尽管阅读了和的文档,但我找不到对我的用例的响应,因为示例只显示了简单的用例

我有一个显示按钮的React组件。
onClick
处理程序设置加载布尔值并调用外部API。我想断言,当我们单击按钮时,组件显示加载指示器

以下是组件:

export default function MyButton(): ReactElement {
    const [loading, setLoading] = useState<boolean>(false);
    const [data, setData] = useState<any>(null);

    const onClick = async (): Promise<void> => {
        setLoading(true);

        const response = await fetch('/uri');
        setData(await response.json());

        setLoading(false);
    };

    if (loading) {
        return <small>Loading...</small>;
    }

    return (
        <div>
            <button onClick={onClick}>Click Me!</button>

            <div>
                {data}
            </div>
        </div>
    );
}
导出默认函数MyButton():ReactElement{
const[loading,setLoading]=useState(false);
const[data,setData]=useState(null);
const onClick=async():Promise=>{
设置加载(真);
const response=wait fetch('/uri');
setData(wait response.json());
设置加载(假);
};
如果(装载){
返回装载。。。;
}
返回(
点击我!
{data}
);
}
下面是测试:

test('should display Loading...', async () => {
    window.fetch = () => Promise.resolve({
        json: () => ({
            item1: 'item1',
            item2: 'item2',
        }),
    });

    const component = mount(<MyButton />);

    // Case 1 ✅ => validates the assertion BUT displays the following warning
    component.find('button').simulate('click');
    // Warning: An update to MyButton 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 */
    // This ensures that you're testing the behavior the user would see in the browser. Learn more at [URL to fb removed because SO does not accept it]

    // Case 2 ❌ => fails the assertion AND displays the warning above
    act(() => {
        component.find('button').simulate('click');
    });

    // Case 3 ❌ => fails the assertion BUT does not display the warning
    await act(async () => {
        component.find('button').simulate('click');
    });

    expect(component.debug()).toContain('Loading...');
});
test('应该显示加载…',async()=>{
window.fetch=()=>Promise.resolve({
json:()=>({
第1项:“第1项”,
第2项:“第2项”,
}),
});
const component=mount();
//案例1✅ => 验证断言,但显示以下警告
component.find('button')。simulate('click');
//警告:测试中对MyButton的更新未包装在act(…)中。
//测试时,应将导致React状态更新的代码包装到act(…):
//行动(()=>{
/*触发更新状态的事件*/
// });
/*在输出上断言*/
//这可确保您正在测试用户在浏览器中看到的行为。有关详细信息,请访问[URL to fb removed,因为SO不接受它]
//案例2❌ => 断言失败并显示上述警告
行动(()=>{
component.find('button')。simulate('click');
});
//案例3❌ => 断言失败,但不显示警告
等待动作(异步()=>{
component.find('button')。simulate('click');
});
expect(component.debug()).toContain('Loading…');
});
如您所见,如果我消除了警告,我的测试将不再令人满意,因为它将等待承诺的解决。我们如何在使用
act
时断言中间状态更改


谢谢。

只需手动解决承诺:

const mockedData = {
  json: () => ({
    item1: 'item1',
    item2: 'item2',
  }),
};
let resolver;
window.fetch = () => new Promise((_resolver) => {
  resolver = _resolver;
});

// ....
await act(async () => {
  component.find('button').simulate('click');
});
expect(component.debug()).toContain('Loading...');
resolver(mockedData);
expect(component.debug()).not.toContain('Loading...');

PS但是为了可读性,我宁愿有两个单独的测试:一个是
newpromise()和另一个带有
Promise.resolve(mockedData)
的会自动解析的

问题是元素根本不在输出中。并不是说我找不到。接得好!谢谢同意两个单独的测试。我还必须为未解决的承诺测试添加一个
component.update()
,以便在断言之前更新组件。一切都好。