[英]How to test/mock a fetch api in a React Component using Jest?
I'm a newbie on test driven development, and I came across a section regarding testing/mocking a fetch api.我是测试驱动开发的新手,我遇到了关于测试/模拟获取 api 的部分。 But I'm struggling to write my own test.但我正在努力编写自己的测试。 I built a simple weather app just to test/mock the fetch using jest.我构建了一个简单的天气应用程序,只是为了使用 jest 测试/模拟获取。 But the test keeps failing.但是测试一直失败。 I keep getting errors like:我不断收到以下错误:
Invalid hook call.无效的挂钩调用。 Hooks can only be called inside of the body of a function component.钩子只能在 function 组件的主体内部调用。 This could happen for one of the following reasons: And not just that, I do not know where I am going wrong, so I came here to ask for tips on how I could mock/improve my test so that it can be successful.这可能是由于以下原因之一发生的:不仅如此,我不知道我哪里出错了,所以我来这里询问有关如何模拟/改进我的测试以使其成功的提示。 H H
Here's my React code: (App.js)这是我的反应代码:(App.js)
const [search, setSearch] = useState('');
const [weather, setWeather] = useState({});
const handleChange = (e) => {
setSearch(e.target.value)
}
//function returns a promise
const WeatherData = async (e) => {
if (e.key === "Enter") {
await fetch(`${api.baseURL}weather?q=${search}&appid=${api.key}`)
.then(data => data.json())
.then(city => {
//console.log(city)
setSearch('')
setWeather(city)
})
}
}
const currentDate = (d) => {
let months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
let days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
let day = days[d.getDay()];
let month = months[d.getMonth()];
let year = d.getFullYear();
let date = d.getDate();
return `${day} ${date} ${month} ${year}`
}
return (
<div className="App">
<h2>International Weather</h2>
<div className="wrapper">
<input type="text" id="search-field" placeholder='Search...' onChange={handleChange} onKeyPress={WeatherData} />
{(typeof weather.main != "undefined") ? (
<div className='weather-box'>
<h2>{weather.name}, {weather.sys.country}</h2>
<h2> {currentDate(new Date())} </h2>
<div id="weather">
<div className="details" id="degrees">{(weather.main.temp - 273.15).toFixed(2)}°C</div>
<div className="details" id="clouds">{weather.weather[0].main}</div>
</div>
</div>
) : (" ")}
</div>
</div>
);
}
And my App.js code:还有我的 App.js 代码:
import { render, screen } from "@testing-library/react";
import App from "./App";
//creating a snapshot test to test if the rendered component is the same as the snapshot app
test("snapshot is correct", () => {
const tree = render(<App />);
expect(tree).toMatchSnapshot();
});
//test whether the function works
test("fetch works correctly", async () => {
App(
JSON.stringify({
results: [{ user: "mandla", age: 43 }],
})
).then((data) => {
expect(data).toBe();
});
});
Would appreciate if anyone can help me understand the problem and why my solution is not working.如果有人可以帮助我理解问题以及为什么我的解决方案不起作用,我将不胜感激。
You can test the fetch API by any of the below methods.您可以通过以下任何方法测试获取 API。
// This is the function we'll be testing
async function withFetch() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts')
const json = await res.json()
return json
}
// This is the section where we mock `fetch`
const unmockedFetch = global.fetch
beforeAll(() => {
global.fetch = () =>
Promise.resolve({
json: () => Promise.resolve([]),
})
})
afterAll(() => {
global.fetch = unmockedFetch
})
// This is actual testing suite
describe('withFetch', () => {
test('works', async () => {
const json = await withFetch()
expect(Array.isArray(json)).toEqual(true)
expect(json.length).toEqual(0)
})
})
const fetchMock = jest
.spyOn(global, 'fetch')
.mockImplementation(() =>
Promise.resolve({ json: () => Promise.resolve([]) })
)
describe('withFetch', () => {
test('works', async () => {
const json = await withFetch()
// highlight-start
expect(fetchMock).toHaveBeenCalledWith(
'https://jsonplaceholder.typicode.com/posts'
)
// highlight-end
expect(Array.isArray(json)).toEqual(true)
expect(json.length).toEqual(0)
})
})
Please have a look at the below link请看下面的链接
https://benjaminjohnson.me/mocking-fetch https://benjaminjohnson.me/mocking-fetch
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.