[英]Jest how to mock implementation of an API call
正如標題中所述,我試圖模擬一個函數的實現。 我是測試 React 應用程序的新手。 我一直在互聯網上尋找有關如何實現目標的數小時,所以讓我解釋一下。
我已經將 API 調用移動到另一個文件 (/utils/fetchGetCard.js):
export const fetchGetCard = (lang, word) => {
return fetch("/getCard", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ lang: lang, word: word })
}).then(response => response.text())
}
然后我在 SearchCard.jsx 中有一個功能組件:
const searchCard = (event) => {
event.preventDefault();
event.stopPropagation();
if (event.currentTarget.checkValidity() === true) {
setValidated(false);
fetchGetCard(selectInput.current.value, wordInput.current.value)
.then(data => {
if (data === "ERR") {
console.log("Oops, something went wrong!");
} else if (data === "MISSING_WORD") {
console.log("Somehow your word wasn't passed to the backend");
} else {
if (data === '') {
showModal(wordInput.current.value);
} else {
setCardInfo(JSON.parse(data));
setCardLang(selectInput.current.value);
setFound(true);
}
}
}).catch((error) => {
console.error('Error:', error);
})
} else {
setValidated(true);
}
}
searchCard 函數綁定到 Form 組件的 onSubmit(來自 react-bootstrap)。 現在我想做一個測試,在其中渲染組件,然后輸入一些信息並按下按鈕。 在這部分中,我可能想模擬 API 調用以返回正確的硬編碼數據。 最后,我想檢查是否呈現了新組件(基於 API 數據)。 這是我到目前為止:
import SearchCard from './SearchCard.jsx';
import { render, waitFor } from '@testing-library/react';
import { fireEvent, screen } from "@testing-library/dom";
import { fetchGetCard } from "../utils/fetchGetCard.js";
jest.mock("../utils/fetchGetCard.js");
test("render SearchCard when card has been found", async () => {
fetchGetCard.mockImplementation(() => {
`{
"word": "hund",
"pronounciation": "ˈhʉn",
"translation": [
{
"type": "noun",
"meaning": "Its a dog mkay?",
"grammarNoun": {
"countable": "true",
"gender": "masculine",
"singularIndefinite": "en hund",
"singularDefinite": "hunden",
"pluralIndefinite": "hunder",
"pluralDefinite": "hundene"
}
}
]
}`
});
render(<SearchCard />);
const testWordInput = screen.getByTestId("testWordInput");
testWordInput.innerHTML = "hund";
const testButtonSearch = screen.getByTestId("testButtonSearch");
fireEvent.click(testButtonSearch);
expect(fetchGetCard).toHaveBeenCalled();
await waitFor(() => screen.findByTestId("testFoundCard"));
expect(screen.getByText("hʉn")).toBeInTheDocument();
});
任何指導將不勝感激!
編輯 1:將 testWordInput.innerHTML 更改為 testWordInput.value 修復了它,似乎我已經成功地模擬了 fetchGetCard 函數。 不過,似乎 setCardInfo()、setCardLang() 和 setFound()(可能都是 setter)不起作用。 這些方法來自 useState 鈎子。 他們應該工作得很好還是我可以做些什么來改變狀態?
修復了問題:如編輯中所述,我設法從expect(fetchGetCard).toHaveBeenCalled()
獲得了正確的結果。 最后一件事是我的錯,我實際上沒有將“testFoundCard”ID 分配給 DOM 中的任何內容,結果是:
await waitFor(() => expect(screen.getByText("hundene")).toBeInTheDocument());
現在它起作用了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.