下面的测试是通过的,但我收到了以下两次警告,我不知道为什么。有人能帮我弄清楚吗?
console.error
Warning: You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);
at printWarning (../../node_modules/react-test-renderer/cjs/react-test-renderer.development.js:120:30)
at error (../../node_modules/react-test-renderer/cjs/react-test-renderer.development.js:92:5)
at ../../node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14953:13
at tryCallOne (../../node_modules/react-native/node_modules/promise/lib/core.js:37:12)
at ../../node_modules/react-native/node_modules/promise/lib/core.js:123:15
at flush (../../node_modules/asap/raw.js:50:29)import { fireEvent } from '@testing-library/react-native'
import { renderScreen } from 'test/render'
describe('screens/home', () => {
it('should render and redirect to the EventScreen', async () => {
const {
getByA11yLabel,
findByA11yLabel,
findAllByA11yLabel,
toJSON
} = renderScreen('Main')
expect(toJSON()).toMatchSnapshot('Default render')
const title = 'New event'
const titleInput = getByA11yLabel('event.title')
// Change title - sync fn
fireEvent.changeText(titleInput, title)
// Create button should be visible
const createButton = await findByA11yLabel('event.create')
expect(titleInput.props.value).toBe(title)
expect(createButton).toBeTruthy()
expect(toJSON()).toMatchSnapshot('Change title')
// Create event - async fn
fireEvent.press(createButton)
// The app should be redirected to the EventScreen
const titleInputs = await findAllByA11yLabel('event.title')
const upsertButton = await findByA11yLabel('event.upsert')
expect(toJSON()).toMatchSnapshot('Create event')
expect(titleInputs).toHaveLength(2)
expect(titleInputs[0].props.value).toBe('') // @MainScreen
expect(titleInputs[1].props.value).toBe(title) // @EventScreen
expect(upsertButton).toBeTruthy()
})
})act- 链接包装act-链接。findBy*也会自动用act - 链接包装。依赖关系:
发布于 2021-09-16 02:58:13
如果您已经用尽了所有其他调试工作,并且非常肯定您的代码编写正确,那么它可能与用react-native/jest-preset替换global.Promise (参见问题)有关。
在这种情况下,问题的解决方案是覆盖/修补jest预置,以首先保存原始的全局承诺,应用react-native/jest-preset,然后恢复原始承诺(覆盖模拟版本)。这允许我在与呈现无关的测试中使用await,而不会触发可怕的
console.error
Warning: You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);此片段展示了执行此修补程序的一种方法:await/commit/64a76486f31bdc41f5c240d28263285683755938
发布于 2020-11-25 02:18:27
我也面临着同样的问题。在我的案例中,我在组件中使用了useEffect。在进行测试时,它促使我将呈现包装在一个act()调用中。一旦我这样做,即act(async () => ...),我的初始问题就解决了,但是我得到了上面提到的错误(Warning: You called act(async () => ...) without await.)。我必须在我的测试中使用await act(async () => ...)来解决这个问题。虽然我仍然不知道为什么要这样做。
作为参考,我将使用await act(async () => ...);添加一个完整的示例组件和相应的测试
LocationComponent.tsx
/** @jsx jsx */
import { jsx } from 'theme-ui';
import { FunctionComponent, useEffect, useState } from 'react';
type Coordinate = {
latitude: number;
longitude: number;
};
const LocationComponent: FunctionComponent<any> = () => {
const [coordinate, setCoordinate] = useState<Coordinate>();
const [sharedLocation, setSharedLocation] = useState<boolean>();
useEffect(() => {
let mounted = true;
if (!coordinate && navigator) {
navigator.geolocation.getCurrentPosition(function (position) {
setCoordinate({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
});
});
navigator.permissions
.query({ name: 'geolocation' })
.then(function (result) {
if (mounted) setSharedLocation(result.state === 'granted');
});
}
return () => (mounted = false);
});
return (
<>
<div>Location shared:{sharedLocation ? 'Yes' : 'No'}</div>
<div>Latitude:{coordinate?.latitude}</div>
<div>Longitude:{coordinate?.longitude}</div>
</>
);
};
export default LocationComponent;LocationComponent.spec.tsx
import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import LocationComponent from '../../../../../src/components/scheduler/location/LocationComponent';
const TEST_COORDS = {
latitude: 41.8817089,
longitude: -87.643301,
};
global.navigator.permissions = {
query: jest
.fn()
.mockImplementationOnce(() => Promise.resolve({ state: 'granted' })),
};
global.navigator.geolocation = {
getCurrentPosition: jest.fn().mockImplementationOnce((success) =>
Promise.resolve(
success({
coords: TEST_COORDS,
})
)
),
};
describe("Location Component when location share is 'granted'", () => {
it('should display current location details', async () => {
await act(async () => {
const { getByText } = render(<LocationComponent />);
/*expect(
await waitFor(() => getByText('Location shared:Yes'))
).toBeInTheDocument();*/
expect(
await waitFor(() => getByText('Latitude:41.8817089'))
).toBeInTheDocument();
expect(
await waitFor(() => getByText('Longitude:-87.643301'))
).toBeInTheDocument();
});
});
});https://stackoverflow.com/questions/64952449
复制相似问题