1

我正在测试Checkout其中有两个 axios.get调用的组件useEffect,如下所示:

    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);
    }, []);

第一个调用是使用axiosMockfrom__mocks__/axios.js方法模拟的:

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);

无法看到更新的组件。

如果我screen.debug()注意到cartTotalaxios模拟响应中设置的内容在发生时尚未设置render,导致渲染Form--组件的条件cartTotal > 1500false.

再次感谢小伙伴们!

4

1 回答 1

0

根据@jonrsharpe 评论和 Jest docs- https://jestjs.io/docs/mock-function-api#mockfnmockresolvedvalueoncevalue - 我可以通过链接 模拟两个连续的 axios 调用mockResolvedValueOnce。我一开始是分开使用它们的。

axiosMock.get.mockResolvedValueOnce({ data: 1600 });
axiosMock.get.mockResolvedValueOnce({ data: 120});

axiosMock.get
    .mockResolvedValueOnce({ data: 1600 })
    .mockResolvedValueOnce({ data: 120 })
于 2021-04-22T17:51:15.800 回答