App
component is
应用程序组件为
function App() {
const [data, setData] = useState({});
useEffect(() => {
fetch("/home")
.then((res) => {
console.log(`got response ${JSON.stringify(res)}`);
return res.json(); //return json from res
})
.then((data) => { //data is the json returned previously. Promise chaining
console.log(`data : ${JSON.stringify(data)}`);
setData(data) //override previous value of data object with value of received json object.
});
}, []);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
{!data ? "No data received" : Object.keys(data).map(key => (
<option key={key} value={key}>{data[key]}</option>))
}
</header>
</div>
);
}
To test, it I have written this code
为了测试,我写了这段代码
test('renders homepage', () => {
render(<App />);
const linkElement = screen.getByText("welcome");
expect(linkElement).toBeInTheDocument();
});
I am getting error:
我收到错误消息:
TestingLibraryElementError: Unable to find an element with the text: welcome. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
TestingLibraryElementError:找不到文本为:欢迎的元素。这可能是因为文本由多个元素组成。在这种情况下,您可以为您的文本匹配器提供一个函数,使您的匹配器更加灵活。
I am assuming it is because the component is not fetching data (/home
) from server. How do I get data from server (which is a simple object {message : "welcome"}
before rendering the App
component? Could I get data from server or do I need to mock or could I do both ?
我认为这是因为组件没有从服务器获取数据(/home)。在呈现App组件之前,如何从服务器(这是一个简单的对象{Message:“Welcome”})获取数据?我可以从服务器获取数据吗?或者我需要模拟吗?或者我可以两者兼而有之?
更多回答
Of course you don't want to get data from the real server. For one thing that's achingly slow from a low-level test perspective, and for another you can then only test what it currently returns (and not what happens if it responds differently, errors, etc.). Either mock fetch itself or use e.g. MSW to mock the network level: blog.jonrshar.pe/2020/Nov/22/js-tdd-e2e.html.
当然,您不希望从真实的服务器获取数据。一方面,从低级测试的角度来看,这非常慢,另一方面,您只能测试它当前返回的内容(而不能测试如果它以不同的方式响应、错误等会发生什么)。Mock抓取自身或使用例如MSW来模拟网络级别:blog.jonrShar.pe/2020/nov/22/js-tdd-e2e.html。
I appreciate the politeness you show when confirming what I intend to do. Not many do that. Thanks. I was hoping for both - real data server as well mocks for error cases. I do understand your point however.
我很感激你在确认我打算做的事情时表现出的礼貌。这样做的人不多。谢谢。我希望两者都有--真实的数据服务器以及错误案例的模拟。然而,我确实理解你的观点。
优秀答案推荐
Your test likely doesn't know how to handle fetch
with the API request by its own, hence it never got the response to display in the UI, causing the assertion to fail.
您的测试可能不知道如何处理API请求本身的FETCH,因此它从未得到要在UI中显示的响应,从而导致断言失败。
For your case, add a mock fetch
to return the response that you desired (in this case {message: 'welcome'}
) by adding --
对于您的情况,添加一个模拟获取以返回所需的响应(在本例中为{Message:‘欢迎’}),方法是添加--
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ message: 'welcome }), // <-- mock response
})
);
beforeEach(() => {
fetch.mockClear();
});
Add those, and run the test again, and it should be working as you were hoping for now.
添加这些,并再次运行测试,它应该像您希望的那样工作。
If that's not the case, the helpful utility function can help you identify what the current DOM looks like by running screen.debug()
. Good luck!
如果不是这样,这个有用的实用函数可以通过运行creen.debug()来帮助您识别当前的DOM。祝好运!
更多回答
我是一名优秀的程序员,十分优秀!