如何使用jestjs使用window.location.reload()刷新页面以模拟真实行为?
测试组件时,我不能强迫我的页面刷新。
我在React中有一个功能分量,当按下按钮时,请刷新页面。 这是我尝试尽可能简化的组件:
import { useLocation } from "react-router-dom";
const Component: React.FC<{ initialData?: string | undefined }> = ({ initialData = undefined }) => {
const [someInternalData, setSomeInternalData] = useState(initialData);
const [someBoolean, setSomeBoolean] = useState(false);
const location:any = useLocation();
useEffect(() =>
{
if(location.state == null){
console.log("first implementation");
} else {
const someDataFromLocation:string|undefined = location.state.someData;
if(someDataFromLocation) {
setInternalData(someDataFromLocation);
setSomeBoolean(true);
}
}
}
,
[setSomeInternalData]
);
function refreshPage() {
window.history.replaceState({}, document.title);
window.location.reload();
}
return(
<div>
<div>
<button type="button" data-testid="refresh-button" onClick={refreshPage}>Refresh</button>
</div>
...//Need of the variable someBoolean for decide of what to display after
</div>
);
}
export default Component;
为了测试此组件,我在某个时候进行了以下测试,我想调用window.location.reload()方法:
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { render, screen, fireEvent, waitFor, cleanup } from '@testing-library/react';
import Component from './Component';
//Other mock function for axios and child component but I don't need it for the problematic part of my test, I don't think it's the problem.
jest.mock('axios');
const mockChildComponent = jest.fn();
describe('Component', () => {
afterEach(cleanup);
beforeEach(()=>{
jest.clearAllMocks()
})
const reload = window.location.reload;
beforeAll(() => {
Object.defineProperty(window, 'location', {
value: { reload: jest.fn() }
});
});
afterAll(() => {
window.location.reload = reload;
});
test('it can be clicked', async () => {
jest.spyOn(window.location, 'reload');
render(<Router>
<Sessions />
</Router>,);
//I then test the different functionality of my component which works very well until I need to call window.location.reload in my component
fireEvent.click(screen.getByTestId(/refresh-button/i));
await waitFor(() => {
expect(window.location.reload).toHaveBeenCalledTimes(1); //OK but it's normal that it works because I mocked it
//Expect some element to be visible on the page after I refresh but fail because window.location.state didn't work and I still have my old page
expect(screen.queryByTestId(/some-test-id/i)).toBeInTheDocument();
//Expect some other element to not be visible on the page after I refresh but fail because window.location.state didn't work and I still have my old page
expect(screen.queryByTestId(/some-other-test-id/i)).toBeNull();
});
});
});
正如我尝试在评论中解释的那样,在测试了效果很好的组件的不同功能之后,我然后测试“刷新”按钮。
一旦我进入将使用window.location.reload()
的测试部分,该测试可以继续,但页面未重新加载,数据保持与在开始时相同测试并且不是重置为0。
您知道如何在模拟的window.location.reload()中强制页面刷新吗?
如果您花时间帮助我,请提前感谢您
I can't force my page to refresh when testing my component.
I have a functional component in React that when a button is pressed refreshes the page.
Here is the component that I tried to simplify as much as possible :
import { useLocation } from "react-router-dom";
const Component: React.FC<{ initialData?: string | undefined }> = ({ initialData = undefined }) => {
const [someInternalData, setSomeInternalData] = useState(initialData);
const [someBoolean, setSomeBoolean] = useState(false);
const location:any = useLocation();
useEffect(() =>
{
if(location.state == null){
console.log("first implementation");
} else {
const someDataFromLocation:string|undefined = location.state.someData;
if(someDataFromLocation) {
setInternalData(someDataFromLocation);
setSomeBoolean(true);
}
}
}
,
[setSomeInternalData]
);
function refreshPage() {
window.history.replaceState({}, document.title);
window.location.reload();
}
return(
<div>
<div>
<button type="button" data-testid="refresh-button" onClick={refreshPage}>Refresh</button>
</div>
...//Need of the variable someBoolean for decide of what to display after
</div>
);
}
export default Component;
To test this component I made the following test in which I want to call the window.location.reload() method at some point:
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { render, screen, fireEvent, waitFor, cleanup } from '@testing-library/react';
import Component from './Component';
//Other mock function for axios and child component but I don't need it for the problematic part of my test, I don't think it's the problem.
jest.mock('axios');
const mockChildComponent = jest.fn();
describe('Component', () => {
afterEach(cleanup);
beforeEach(()=>{
jest.clearAllMocks()
})
const reload = window.location.reload;
beforeAll(() => {
Object.defineProperty(window, 'location', {
value: { reload: jest.fn() }
});
});
afterAll(() => {
window.location.reload = reload;
});
test('it can be clicked', async () => {
jest.spyOn(window.location, 'reload');
render(<Router>
<Sessions />
</Router>,);
//I then test the different functionality of my component which works very well until I need to call window.location.reload in my component
fireEvent.click(screen.getByTestId(/refresh-button/i));
await waitFor(() => {
expect(window.location.reload).toHaveBeenCalledTimes(1); //OK but it's normal that it works because I mocked it
//Expect some element to be visible on the page after I refresh but fail because window.location.state didn't work and I still have my old page
expect(screen.queryByTestId(/some-test-id/i)).toBeInTheDocument();
//Expect some other element to not be visible on the page after I refresh but fail because window.location.state didn't work and I still have my old page
expect(screen.queryByTestId(/some-other-test-id/i)).toBeNull();
});
});
});
As I tried to explain in the comments, after testing the different functionalities of my component which works well, I then test the refresh button.
Once I get to the part of the test that will use window.location.reload()
, the test can continue but the page doesn't reload, the data remains the same as at the beginning of the test and is not reset to 0.
Do you know how to force a page refresh in the mocked method of window.location.reload()?
Thank you in advance if you take the time to help me
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论