我目前有这个反应组件,它显示从 api 检索的服务列表(为简单起见删除了一些代码):
function Services(props) {
const [services, setServices] = useState([]);
const [page_nr, setPage_nr] = useState(0);
const [nameSearch, setNameSearch] = useState("");
const [domainSearch, setDomainSearch] = useState("");
let match = useRouteMatch();
let num_on_page = 20;
const get_services = () => {
let skip = page_nr*num_on_page;
fetch('https://myurl/api/services?limit={num_on_page}&skip={skip}', {
method: 'GET'
})
.then((res) => res.json())
.then((result) => setServices(result._embedded.serviceList))
.catch((err) => console.log('error'))
}
const listItems = services.map((service) =>
<li key={service.id}><Link to={`${match.url}/${service.id}`}>
<Service name={service.name} domain={service.domain} description={service.description} /></Link></li>
);
useEffect(() => {
if (nameSearch === "" || domainSearch === "") {
get_services();
}
});
return (
<Switch>
<Route path={`${match.path}/create`} component={ServiceCreate}/>
<Route path={`${match.path}/:id`} component={ServicePage}/>
<Route path={match.path}>
<div className="Services">
<h1>Diensten</h1>
<hr id="services_line"/>
<Link to={`${match.url}/create`}>
<button type="button" className="btn btn-primary">Nieuwe Dienst</button>
</Link>
<ul>{listItems}</ul>
<input type="button" value="Vorige" disabled={page_nr == 0} onClick={() => setPage_nr(page_nr-1)}/>
<input type="button" value="Volgende" disabled={services.length < num_on_page} onClick={() => setPage_nr(page_nr+1)}/>
</div>
</Route>
</Switch>
);
}
export default Services;
我编写了以下测试代码,我想模拟 fetch 函数,以便我可以测试渲染的数量是否正确,这里我使用 Mock Service Worker:
import 'whatwg-fetch';
import { setupWorker, rest } from 'msw';
import { setupServer } from 'msw/node';
const fakeData = {
_embedded: {
serviceList: [{id: 100, name:"naam 1", description:"een omschrijving van de dienst", domain: "domein 1"},
{id: 101, name:"naam 1", description:"een omschrijving van de dienst", domain: "domein 1"},
{id: 102, name:"naam 1", description:"een omschrijving van de dienst", domain: "domein 1"},
{id: 104, name:"naam 1", description:"een omschrijving van de dienst", domain: "domein 1"},
{id: 105, name:"naam 1", description:"een omschrijving van de dienst", domain: "domein 1"},
{id: 106, name:"naam 1", description:"een omschrijving van de dienst", domain: "domein 1"},
{id: 107, name:"naam 1", description:"een omschrijving van de dienst", domain: "domein 1"},
{id: 108, name:"naam 1", description:"een omschrijving van de dienst", domain: "domein 1"}]
}
};
const server = setupServer(
rest.get("https://sel2-4.ugent.be/api/services", (req, res, ctx) => {
return res(ctx.status(200), ctx.json(fakeData))
}));
describe('Test Services', () => {
beforeAll(() => server.listen());
afterAll(() => server.close());
let wrapper = null;
const history = createMemoryHistory()
history.push('/services')
beforeEach(async () => {
await act(async () => {
wrapper = mount(<Router history={history}><Services/></Router>);
});
wrapper.update();
})
afterEach(() => {
wrapper = null;
server.resetHandlers()
})
it('should render correct fetched amount', async () => {
expect(wrapper.find(Service).length).toBe(8);
})
});
当我运行测试它失败并显示长度为 0(如果我编辑const [services, setServices] = useState([]);
为数组中已有项目,则长度不同于 0)。似乎 fetch 甚至没有被执行。现在我尝试了许多选项来模拟 fetch 函数,但它们似乎都不起作用。我在这里做错了什么以及测试使用 fetch 的反应钩子的方法应该是什么?