我正在测试组件Checkout
,它的useEffect
内部有两个axios.get
调用,如下所示:
useEffect(() => {
let isMounted = true;
if (isMounted) {
axios
.get("/cart/get-total") // 1st call
.then((res) => {
setCartTotal(res.data)
);
})
.catch((err) => {
console.error(err);
axios
.get("/cart/get-subtotal") // 2nd call
.then((res) => {
setUpfrontPayPalPayment(res.data); // 7% comission
})
.catch((err) => {
console.error(err);
});
}
return () => (isMounted = false);
}, []);
使用__mocks__/axios.js
方法中的axiosMock
模拟第一个调用:
axios.js
export default {
post: jest.fn().mockResolvedValue({ data: {} }),
get: jest.fn().mockResolvedValue({ data: {} }),
// getAgain: jest.fn().mockResolvedValue({ data: {} }), // nope
};
但是,我不知道如何模拟第二个调用,它也是
get
调用。
Checkout.test.js
jest.unmock("axios"); // unmock from previous test
import axiosMock from "../__mocks__/axios";
// faked props
const userInfo = {
userName: "paco",
userPhone: "1234567890",
};
const loggedIn = true;
describe("Checkout Component", () => {
axiosMock.get.mockResolvedValueOnce({ data: 1600 });
// axiosMock.get.mockResolvedValueOnce({ data: 120 }); // tried this for the second
// axiosMock.getAgain.mockResolvedValueOnce({ data: 120 }); // also this
it("renders", async () => {
await act(async () => {
render(
<HashRouter>
<Checkout userInfo={userInfo} loggedIn={loggedIn} />
</HashRouter>
);
screen.debug();
});
});
});
Checkout.js组件,如果您想深入了解:
import axios from "axios";
import React, { useEffect, useState, useRef, useContext } from "react";
const Checkout = (props) => {
// several useStates
const context = useContext(Context);
// this method gets fired onSubmit
const handleTransferSubmit = () => {
// two axios.post consecutive calls that should not affect at
// all since they are fired onSubmit
};
// get user info and cart total-subtotal
useEffect(() => {
let isMounted = true;
// if phone info available set it
props.userInfo["userPhone"] &&
setPhone(parseInt(props.userInfo["userPhone"]));
if (isMounted) {
axios
.get("/cart/get-total")
.then((res) => {
setCartTotal(
res.data
);
})
.catch((err) => {
console.error(err);
context.notifyToaster('error', 'Tenemos problemas con el servidor. Intenta más tarde');
});
axios
.get("/cart/get-subtotal")
.then((res) => {
setUpfrontPayPalPayment(res.data); // 7% comission
})
.catch((err) => {
console.error(err);
context.notifyToaster(
"error",
"Tenemos problemas con el servidor. Intenta más tarde"
);
});
}
return () => (isMounted = false);
}, []);
// form validations
useEffect(() => {
let isMounted = true;
return () => (isMounted = false);
}, [
orderName,
phone,
CP,
streetName,
addressNumber,
deliveryDay,
deliverySchedule,
addressDetails,
paymentMode,
]);
return (
<div className="container">
{!loader ? (
props.loggedIn && cartTotal > 1500 ? (
<div style={{ marginBottom: "6rem" }}>
<Form>
{/* all the form info */}
<Button
className="mb-5"
variant="primary"
type="submit"
disabled={buttonIsActive ? false : true}
onClick={handleTransferSubmit}
>
Generar orden
</Button>
</Form>
</div>
) : (
<div>{/* if user is not logged in he can't see the form */}</div>
)
) : (
<CustomLoader />
)}
</div>
);
};
export default withRouter(Checkout);
无法查看更新的组件。
如果Iscreen.debug()
,我注意到当render
发生时,在axios
模拟响应中设置的cartTotal
还没有设置,导致呈现-Form
-分量cartTotal > 1500
的条件是false
。
再次感谢,伙计们!
根据@jonrsharpe评论和Jestdocs
-https://jestjs.io/docs/mock-function-api#mockfnmockresolvedvalueoncevalue-我可以通过链接mockResolvedValueOnce
来模拟两个连续的axios调用。我一开始是分开使用的。
之前
axiosMock.get.mockResolvedValueOnce({ data: 1600 });
axiosMock.get.mockResolvedValueOnce({ data: 120});
之后
axiosMock.get
.mockResolvedValueOnce({ data: 1600 })
.mockResolvedValueOnce({ data: 120 })