为什么Jest不会对这个函数进行间谍活动?

huangapple go评论71阅读模式
英文:

Why doesn't Jest spy on the function?

问题

我写了一个简单的自定义 Hook:

import { IsValueAlreadyRegistered } from "../../entities/registration/actions";

export const useForgetPassword = () => {
  const activeStep = 0;
  const email = "any@any.com";

  const nextStep = (): void => {
    let isThereError: boolean = false;

    switch (activeStep) {
      case 0:
        if (!isThereError) {
          IsValueAlreadyRegistered(email, "isEmailRegistered");
        }
        break;
    }
  };

  return { nextStep };
};

它只有一个函数我导入。我想对它进行监视,确保它以预期参数被调用。

这是我的测试:

import { renderHook } from "@testing-library/react";
import { useForgetPassword } from ".";
import * as Registered from "../../entities/registration/actions";

describe("useForgetPassword", () => {
  const { result } = renderHook(() => useForgetPassword());

  const IsValueAlreadyRegisteredMock = jest.fn();

  test("nextStep", () => {
    jest
      .spyOn(Registered, "IsValueAlreadyRegistered")
      .mockReturnValue(IsValueAlreadyRegisteredMock);

    const { nextStep } = result.current;
    nextStep();

    expect(IsValueAlreadyRegisteredMock).toBeCalledWith(
      "any@any.com",
      "isEmailRegistered"
    );
  });
});

我检查了导入函数 IsValueAlreadyRegistered 的路径和我想要监视的路径,它们是匹配的。

这是函数代码 IsValueAlreadyRegistered

import { registrationFormSlice } from ".";
import { AppDispatch } from "../store";

const { setEmail } = registrationFormSlice.actions;

export const IsValueAlreadyRegistered =
  (value: string, process: string) => async (dispatch: AppDispatch) => {
    switch (process) {
      case "isEmailRegistered":
        dispatch(setEmail({ value, error: false, text: "" }));
        break;
    }
  };

问题是 Jest 表示未调用 IsValueAlreadyRegistered 函数。我不明白为什么?

我跟踪了代码执行,并确保调用了函数 IsValueAlreadyRegistered 并传递了我需要的参数:

我认为这可能是由于在 IsValueAlreadyRegistered 中使用了 dispatch: AppDispatch,因为在执行代码时,调试器没有切换到 IsValueAlreadyRegistered 函数。但是当你监视一个函数时,它必须执行该函数的代码吗?在我看来,不是,它只是被 jest.fn() 替换。

我也假设也许我使用它不正确:

jest
      .spyOn(Registered, "IsValueAlreadyRegistered")
      .mockReturnValue(IsValueAlreadyRegisteredMock);

告诉我我哪里出错了,我确定这只是一些小事情,但我看不到它。非常感谢您提前提供的任何帮助!

英文:

I wrote a simple custom Hook:

import { IsValueAlreadyRegistered } from "../../entities/registration/actions";

export const useForgetPassword = () => {
  const activeStep = 0;
  const email = "any@any.com";

  const nextStep = (): void => {
    let isThereError: boolean = false;

    switch (activeStep) {
      case 0:
        if (!isThereError) {
          IsValueAlreadyRegistered(email, "isEmailRegistered");
        }
        break;
    }
  };

  return { nextStep };
};

It has only one function that I import. I want to spy on it and make sure that it is called with the expected arguments.

This is my test:

import { renderHook } from "@testing-library/react";
import { useForgetPassword } from ".";
import * as Registered from "../../entities/registration/actions";

describe("useForgetPassword", () => {
  const { result } = renderHook(() => useForgetPassword());

  const IsValueAlreadyRegisteredMock = jest.fn();

  test("nextStep", () => {
    jest
      .spyOn(Registered, "IsValueAlreadyRegistered")
      .mockReturnValue(IsValueAlreadyRegisteredMock);

    const { nextStep } = result.current;
    nextStep();

    expect(IsValueAlreadyRegisteredMock).toBeCalledWith(
      "any@any.com",
      "isEmailRegistered"
    );
  });
});

I checked the path where I import the function IsValueAlreadyRegistered and the path I want to spy on, they match.

Here is the function code IsValueAlreadyRegistered:

import { registrationFormSlice } from ".";
import { AppDispatch } from "../store";

const { setEmail } = registrationFormSlice.actions;

export const IsValueAlreadyRegistered =
  (value: string, process: string) => async (dispatch: AppDispatch) => {
    switch (process) {
      case "isEmailRegistered":
        dispatch(setEmail({ value, error: false, text: "" }));
        break;
    }
  };

The problem is that Jest indicates that the IsValueAlreadyRegistered function is not called. I don't understand why?

为什么Jest不会对这个函数进行间谍活动?

I followed the code execution and made sure that the function IsValueAlreadyRegistered is called and the arguments I need are passed to it:

为什么Jest不会对这个函数进行间谍活动?

I suggest that this may be due to the use of dispatch: AppDispatch in IsValueAlreadyRegistered, since when executing the code, the debugger did not switch to the IsValueAlreadyRegistered function. But when you spy on a function, does it have to execute the code of that function? In my opinion, no, it is replaced by just.fn().

I also assume that maybe I'm using it incorrectly :

jest
      .spyOn(Registered, "IsValueAlreadyRegistered")
      .mockReturnValue(IsValueAlreadyRegisteredMock);

Tell me where I made a mistake, I'm sure it's some little thing, but I can't see it. Thank you very much in advance for any help!

答案1

得分: 0

以下是翻译好的部分:

"assertion is wrong, Registered.IsValueAlreadyRegistered is called with "any@any.com" and "isEmailRegistered" parameters.

The mock return value of Registered.IsValueAlreadyRegistered is the IsValueAlreadyRegisteredMock function, it's not called. Your code seems not correct, I guess the IsValueAlreadyRegistered is a redux thunk based on its function signature. So a thunk should be called correctly like:

const dispatch = useDispatch();
dispatch(IsValueAlreadyRegistered(email, 'isEmailRegistered'))

So that the internal function(IsValueAlreadyRegisteredMock) will be called by the redux-thunk middleware.

Anyway, check the correct assertion.

describe("useForgetPassword", () => {
  const { result } = renderHook(() => useForgetPassword());
  const IsValueAlreadyRegisteredMock = jest.fn();

  test("nextStep", () => {
    jest
      .spyOn(Registered, "IsValueAlreadyRegistered")
      .mockReturnValue(IsValueAlreadyRegisteredMock)

    const { nextStep } = result.current;
    nextStep();

    expect(Registered.IsValueAlreadyRegistered).toBeCalledWith(
      "any@any.com",
      "isEmailRegistered"
    );
  });
})
英文:

The assertion is wrong, Registered.IsValueAlreadyRegistered is called with "any@any.com" and "isEmailRegistered" parameters.

The mock return value of Registered.IsValueAlreadyRegistered is the IsValueAlreadyRegisteredMock function, it's not called. Your code seems not correct, I guess the IsValueAlreadyRegistered is a redux thunk based on its function signature. So a thunk should be called correctly like:

const dispatch = useDispatch();
dispatch(IsValueAlreadyRegistered(email, 'isEmailRegistered'))

So that the internal function(IsValueAlreadyRegisteredMock) will be called by the redux-thunk middleware.

Anyway, check the correct assertion.

describe("useForgetPassword", () => {
  const { result } = renderHook(() => useForgetPassword());
  const IsValueAlreadyRegisteredMock = jest.fn();

  test("nextStep", () => {
    jest
      .spyOn(Registered, "IsValueAlreadyRegistered")
      .mockReturnValue(IsValueAlreadyRegisteredMock)

    const { nextStep } = result.current;
    nextStep();

    expect(Registered.IsValueAlreadyRegistered).toBeCalledWith(
      "any@any.com",
      "isEmailRegistered"
    );
  });
})

huangapple
  • 本文由 发表于 2023年5月17日 11:30:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76268377.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定