使用react测试库模拟axios两次



我正在测试组件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 })

最新更新