编写测试以使用 jest 和 react-testing-library 检查本地 setState 调用
Write test to check local setState call with jest and react-testing-library
我目前正在使用 react-testing-library,但似乎不知道如何测试组件的 setState。
在下面的示例中,我尝试根据 API 中的数据测试加载的项目数是否正确。稍后将扩展它以测试诸如项目之间的交互之类的东西。
组件:
...
componentDidMount() {
this.getModules();
}
getModules () {
fetch('http://localhost:4000/api/query')
.then(res => res.json())
.then(res => this.setState({data : res.data}))
.catch(err => console.error(err))
}
...
render() {
return(
<div data-testid="list">
this.state.data.map((item) => {
return <Item key={item.id} data={item}/>
})
</div>
)
}
测试:
...
function renderWithRouter(
ui,
{route = '/', history = createMemoryHistory({initialEntries: [route]})} = {},) {
return {
...render(<Router history={history}>{ui}</Router>),
history,
}
}
...
test('<ListModule> check list items', () => {
const data = [ ... ]
//not sure what to do here, or after this
const { getByTestId } = renderWithRouter(<ListModule />)
...
//test the items loaded
expect(getByTestId('list').children.length).toBe(data.length)
//then will continue testing functionality
})
我知道这与 jest mock 函数有关,但不明白如何使它们与设置状态或模拟 API.
一起工作
示例实现(有效!)
通过更多练习和学习如何使组件可测试,我能够使它正常工作。这里有一个完整的例子供参考:https://gist.github.com/alfonsomunozpomer/de992a9710724eb248be3842029801c8
const data = [...]
fetchMock.restore().getOnce('http://localhost:4000/api/query', JSON.stringify(data));
const { getByText } = renderWithRouter(<ListModule />)
const listItem = await waitForElement(() => getByText('Sample Test Data Title'))
您应该避免直接测试 setState
,因为那是组件的实现细节。您正走在正确的道路上,可以测试是否呈现了正确数量的项目。您可以通过将 window.fetch
替换为 Jest mock function or using the fetch-mock 库来模拟 fetch
函数来为您处理繁重的工作。
// Note that this method does not build the full response object like status codes, headers, etc.
window.fetch = jest.fn(() => {
return Promise.resolve({
json: () => Promise.resolve(fakeData),
});
});
或
import fetchMock from "fetch-mock";
fetchMock.get(url, fakeData);
我目前正在使用 react-testing-library,但似乎不知道如何测试组件的 setState。
在下面的示例中,我尝试根据 API 中的数据测试加载的项目数是否正确。稍后将扩展它以测试诸如项目之间的交互之类的东西。
组件:
...
componentDidMount() {
this.getModules();
}
getModules () {
fetch('http://localhost:4000/api/query')
.then(res => res.json())
.then(res => this.setState({data : res.data}))
.catch(err => console.error(err))
}
...
render() {
return(
<div data-testid="list">
this.state.data.map((item) => {
return <Item key={item.id} data={item}/>
})
</div>
)
}
测试:
...
function renderWithRouter(
ui,
{route = '/', history = createMemoryHistory({initialEntries: [route]})} = {},) {
return {
...render(<Router history={history}>{ui}</Router>),
history,
}
}
...
test('<ListModule> check list items', () => {
const data = [ ... ]
//not sure what to do here, or after this
const { getByTestId } = renderWithRouter(<ListModule />)
...
//test the items loaded
expect(getByTestId('list').children.length).toBe(data.length)
//then will continue testing functionality
})
我知道这与 jest mock 函数有关,但不明白如何使它们与设置状态或模拟 API.
一起工作示例实现(有效!)
通过更多练习和学习如何使组件可测试,我能够使它正常工作。这里有一个完整的例子供参考:https://gist.github.com/alfonsomunozpomer/de992a9710724eb248be3842029801c8
const data = [...]
fetchMock.restore().getOnce('http://localhost:4000/api/query', JSON.stringify(data));
const { getByText } = renderWithRouter(<ListModule />)
const listItem = await waitForElement(() => getByText('Sample Test Data Title'))
您应该避免直接测试 setState
,因为那是组件的实现细节。您正走在正确的道路上,可以测试是否呈现了正确数量的项目。您可以通过将 window.fetch
替换为 Jest mock function or using the fetch-mock 库来模拟 fetch
函数来为您处理繁重的工作。
// Note that this method does not build the full response object like status codes, headers, etc.
window.fetch = jest.fn(() => {
return Promise.resolve({
json: () => Promise.resolve(fakeData),
});
});
或
import fetchMock from "fetch-mock";
fetchMock.get(url, fakeData);