简体   繁体   English

如何在玩笑中模拟 const 方法?

[英]How to mock const method in jest?

I unit test code in typescript, use jest.我在打字稿中单元测试代码,使用开玩笑。 Please teach me how to mock getData to return the expected value.请教我如何模拟getData以返回预期值。 My code as below:我的代码如下:

// File util.ts
export const getData = async () => {
    // Todo something
    return data;
}

// File execution.ts import { getData } from './util';
function execute()
{
    // todo something
    const data = await getData();
    // todo something 
}

The problem is that your function returns a promise.问题是你的函数返回一个承诺。 Depends on how you use it there are several ways to mock it.取决于您如何使用它,有多种方法可以模拟它。

The simplest way would be to mock it directly, but then it will always return the same value:最简单的方法是直接模拟它,但它总是会返回相同的值:

// note, the path is relative to your test file
jest.mock('./util', () => ({ getData: () => 'someValue' }));

If you want to test both the resolved and the rejected case you need to mock getData so it will return a spy where you later on can change the implementation use mockImplementation .如果您想测试已解决和被拒绝的情况,您需要模拟getData以便它返回一个间谍,您以后可以使用mockImplementation更改实现。 You also need to use async/await to make the test work, have a look at the docs about asynchronous testing:您还需要使用async/await来使测试工作,请查看有关异步测试的文档

import { getData } from './util';
jest.mock('./util', () => ({ getData: ()=> jest.fn() }));

it('success case', async () => {
  const result = Promise.resolve('someValue');
  getData.mockImplementation(() => result);

  // call your function to test
  await result; // you need to use await to make jest aware of the promise
});

it('error case', async () => {
  const result = Promise.reject(new Error('someError'));
  getData.mockImplementation(() => result);

  // call your function to test
  await expect(result).rejects.toThrow('someError');
});

Try the following in your test file.在您的测试文件中尝试以下操作。 Import the function from the module.从模块导入函数。

 import { getData } from './util';

Then mock the module with the function and its return value after all the import statements然后在所有导入语句之后用函数及其返回值模拟模块

jest.mock('./util', () => ({ getData: jest.fn() }))
getData.mockReturnValue("abc");

Then use it in your tests.然后在您的测试中使用它。

Because mocking expression functions can be a real pain to get right, I'm posting a full example below.因为模拟表达式函数很难做到正确,所以我在下面发布了一个完整的例子。

Scenario设想

Let's say we want to test some code that performs some REST call, but we don't want the actual REST call to be made:假设我们想测试一些执行 REST 调用的代码,但我们不希望进行实际的 REST 调用:

// doWithApi.ts

export const doSomethingWithRest = () => {
    post("some-url", 123);
}

Where the post is a function expression in a separate file:其中post是单独文件中的函数表达式

// apiHelpers.ts

export const post = (url: string, num: number) => {
    throw Error("I'm a REST call that should not run during unit tests!");
}

Setup设置

Since the post function is used directly (and not passed in as a parameter), we must create a mock file that Jest can use during tests as a replacement for the real post function:由于post函数是直接使用的(而不是作为参数传入),我们必须创建一个模拟文件,Jest 可以在测试期间使用它来代替真正的post函数:

// __mocks__/apiHelpers.ts

export const post = jest.fn();

Spy and Test间谍和测试

Now, finally inside the actual test, we may do the following:现在,终于在实际测试中,我们可能会执行以下操作:

// mockAndSpyInternals.test.ts

import {doSomethingWithRest} from "./doWithApi";

afterEach(jest.clearAllMocks);   // Resets the spy between tests
jest.mock("./apiHelpers");       // Replaces runtime functions inside 'apiHelpers' with those found inside __mocks__. Path is relative to current file. Note that we reference the file we want to replace, not the mock we replace it with.

test("When doSomethingWithRest is called, a REST call is performed.", () => {

    // If we want to spy on the post method to perform assertions we must add the following lines. 
    // If no spy is wanted, these lines can be omitted. 
    const apiHelpers = require("./apiHelpers");
    const postSpy = jest.spyOn(apiHelpers, "post");

    // Alter the spy if desired (e.g by mocking a resolved promise)
    // postSpy.mockImplementation(() => Promise.resolve({..some object}))

    doSomethingWithRest();

    expect(postSpy).toBeCalledTimes(1)
    expect(postSpy).toHaveBeenCalledWith("some-url", 123);
});

Examples are made using Jest 24.9.0 and Typescript 3.7.4使用 Jest 24.9.0 和 Typescript 3.7.4 制作示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM