【问题标题】:Jest mocked promise function return undefinedJest 嘲笑 promise 函数返回 undefined
【发布时间】:2022-12-07 01:32:56
【问题描述】:

这是我在src/utils/calls/aws.js 的辅助函数

export const loginCognito = (cognitoUser, authenticationDetails) => {
  return new Promise((resolve, reject) => {
    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: resolve,
      onFailure: reject,
      newPasswordRequired: resolve,
    });
  });
};

这是我的测试文件:

import { fireEvent, screen, waitFor } from "@testing-library/react";
import { LoginPage } from "../../../views/LoginPage/LoginPage";
import { renderWithProviders } from "../../__test-utils__/test-utils";
// eslint-disable-next-line jest/no-mocks-import
import { LOCALSTORAGE_ACCESS_TOKEN } from "../../../utils/constants/constant";

const accessToken = "an.access.token";

const promisedResult = {
    "idToken": {
        "jwtToken": "an.access.token",
        "payload": {
            "sub": "354548-5454-c59637523bfd",
            "email_verified": true,
            "iss": "https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_tomahwaf",
            "cognito:username": "john-doe",
            "preferred_username": "john-doe",
            "aud": "client.id.aws",
            "custom:dataInizioContratto": "01/01/2020",
            "event_id": "ee5626d5-ffc2-4ecf-89df-2e1a83c0c174",
            "token_use": "id",
            "auth_time": 1670256322,
            "custom:azienda": "acme",
            "exp": 1670259922,
            "iat": 1670256322,
            "email": "info@example.com"
        }
    },
    "refreshToken": {
        "token": "a.refresh.token"
    },
    "accessToken": {
        "jwtToken": "an.access.token",
        "payload": {
            "sub": "354548-5454-c59637523bfd",
            "event_id": "ee5626d5-ffc2-4ecf-89df-2e1a83c0c174",
            "token_use": "access",
            "scope": "aws.cognito.signin.user.admin",
            "auth_time": 1670256322,
            "iss": "https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_tomahwaf",
            "exp": 1670259922,
            "iat": 1670256322,
            "jti": "083d4b9a-5042-485b-bb65-c66e8ae5b921",
            "client_id": "client.id.aws",
            "username": "john-doe"
        }
    },
    "clockDrift": 0
};

jest.mock("../../../utils/calls/aws.js", () => ({
  //loginCognito: jest.fn().mockReturnValue(Promise.resolve({accessToken: "an.access.token"}))
  //loginCognito: jest.fn(() => Promise.resolve(promisedResult))
  //loginCognito: jest.fn(() => promisedResult)
  loginCognito: jest.fn().mockResolvedValue(promisedResult)
}));

describe("Test LoginPage", () => {

  it("Can press button without userEvent", async () => {

    renderWithProviders(<LoginPage />);

    const inputUsername = screen.getByLabelText(/username/i);
    fireEvent.change(inputUsername, {
      target: {
        value: "info@example.com",
      },
    });

    const inputPassword = screen.getByLabelText(/password/i);
    fireEvent.change(inputPassword, {
      target: {
        value: "thisIsASecretPassword",
      },
    });

    const loginButton = screen.getByRole("button", { name: /login/i });
    fireEvent.click(loginButton);
    await waitFor(() => {
      expect(localStorage.getItem(LOCALSTORAGE_ACCESS_TOKEN)).toEqual(
        accessToken
      );
    });
  });
});

在真实文件(LoginPage)中我有

const handleClick = async () => {
    // Fetch the data from cognito
    const {cognitoUser, authenticationDetails} = loginCognitoUser(currentItem);
    // Call AWS
    try {
      const isLogged = await loginCognito(cognitoUser, authenticationDetails);
      console.log(">>>>>>>>>>>>>>>>>>>", JSON.stringify(isLogged))
    } catch (e) {
      console.log(e)
    }
  };

对于真正的实现,它是有效的,但是当我从测试中调用时,我得到了

console.log
>>>>>>>>>>>>>>>>>>> undefined

at handleClick (src/views/LoginPage/LoginPage.js:52:15)

模拟函数不会“绕过”它返回我想要的东西吗?

我做了 4 次测试,我不知道该怎么做:

//loginCognito: jest.fn().mockReturnValue(Promise.resolve({accessToken: "an.access.token"}))
  //loginCognito: jest.fn(() => Promise.resolve(promisedResult))
  //loginCognito: jest.fn(() => promisedResult)
  loginCognito: jest.fn().mockResolvedValue(promisedResult)

我尝试在我的 aws 函数中添加一个 console.log 并且......如果我删除模拟我有 console.log,所以我认为该函数被正确模拟但无法返回。

编辑号码。 2个

我尝试了另一件事:

export const loginCognito = () => {
  return "ciao"
}

在测试中:

jest.mock("../../../utils/calls/aws.js", () => ({
  loginCognito: jest.fn().mockReturnValue("addio")
}));

被测页面未定义 console.log!

try {
      //const isLogged = await loginCognito(cognitoUser, authenticationDetails);
      const isLogged = loginCognito();
      console.log("==========", isLogged)
    } catch (e) {
      console.log(e)
    }

我是不是不知道它是如何模拟的?

Console

    console.log
      ========== undefined

      at handleClick (src/views/LoginPage/LoginPage.js:55:15)

我需要完全绕过 AWS 功能......

【问题讨论】:

  • 第二次编辑看起来像 jest.mock 从不运行或模拟错误的文件

标签: javascript jestjs mocking


【解决方案1】:

我真的不能说为什么你的代码不起作用,但这就是我编写你的测试的方式:

// import the function you want to mock
import { loginCognito } from "../../../utils/calls/aws.js";

// tell jest to mock your module
jest.mock("../../../utils/calls/aws.js");

// before each test, mock the implementation
beforeEach(() => {
  loginCognito.mockResolvedValue(...);
});

// cleanup after each test
afterEach(() => {
  loginCognito.mockClear(...);
});

如果您使用的是打字稿,则需要让打字稿知道该方法已被模拟。这是通过转换方法来完成的,这主要是打字稿所需的单调乏味。按照惯例,我通常把作品“mock”放在名字前面:

const mockLoginCongnito = loginCognito as jest.MockedFunction<typeof loginCognito>;

【讨论】:

    猜你喜欢
    • 2017-09-11
    • 2015-01-07
    • 2019-07-07
    • 1970-01-01
    • 2021-03-23
    • 2021-09-16
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    相关资源
    最近更新 更多