【问题标题】:Cannot inspect arguments passed to a Jest mocked object无法检查传递给 Jest 模拟对象的参数
【发布时间】:2021-02-05 22:32:57
【问题描述】:

我有一个相当直接的 Typescript 类和方法。我想用 Jest 来测试这个方法来模拟这个方法的依赖:

import {DynamoWorkflow} from '..';
import {Injectable} from '@nestjs/common';

@Injectable()
export class PipelineService {
    getCoverageByServiceName(serviceName: string): Promise<QueryResult<PipelineEvent>> {
        return new DynamoWorkflow().queryPipelineEvents(serviceName);
    }
}

在我的测试中,我想确认传递给方法.queryPipelineEvents() 的参数是我所期望的。我发现这很难完成。

这是我目前的测试:

//setup mock data...
const mockPipelineEvent: PipelineEvent = new PipelineEvent();
mockPipelineEvent.aut = "fake data";
const mockPipelineEvents: PipelineEvent[] = [mockPipelineEvent];
const mockQueryResult = {results: mockPipelineEvents, total: 1};

//setup mock dependency...
jest.mock('../../../../workflows/dynamoworkflow', () => {
  return {
    DynamoWorkflow: jest.fn().mockImplementation(() => {
      return {
        queryPipelineEvents: () => Promise.resolve(mockQueryResult),
      };
    })
  };
});

describe("PipelineService", () => {
  const mockDynamo = mocked(DynamoWorkflow, true);
    
  beforeEach(() => {
    mockDynamo.mockClear(); 
  })

  it("getCoverageByServiceName returns same data as db supplies", () => {
    const methodArg = "foo-service";
    const serviceUnderTest = new PipelineService();
    const actualResult = serviceUnderTest.getCoverageByServiceName(methodArg);

    // Test #1: confirm the dependency was called
    expect(mockDynamo).toHaveBeenCalledTimes(1); //PASSES

    // Test #2: confirm the dependency method was called with the correct argument
    const mockedDynamoInstance = mockDynamo.mock.instances[0];
    const mockedDynamoMethod = mockedDynamoInstance.queryPipelineEvents;
    expect(mockedDynamoMethod.mock.calls[0][0]).toHaveBeenCalledWith(methodArg);  //ERROR HERE on .mock

    // Test #3: confirm the result is what we expect
    expect(actualResult).resolves.toEqual(mockQueryResult); //PASSES
  });
})

此代码将无法编译。消息是Property 'mock' does not exist on type '(serviceName: string) =&gt; Promise&lt;QueryResult&lt;PipelineEvent&gt;&gt;'.ts(2339)

我使用的错误代码块directly from Jest's own documentation.

我尝试过expect(mockDynamo.queryPipelineEvents).toBeCalledWith(methodArg);,但也无法编译,错误提示:Property 'queryPipelineEvents' does not exist on type 'MockedObjectDeep&lt;typeof DynamoWorkflow&gt;'.ts(2339)

我也试过expect(mockDynamo.mock.instances[0].queryPipelineEvents).toBeCalledWith(methodArg);。它编译并运行良好,但失败并显示以下消息:

    expect(received).toBeCalledWith(...expected)

    Matcher error: received value must be a mock or spy function

    Received has value: undefined

      44 |     // expect(mockedDynamoMethod.mock.calls[0][0]).toHaveBeenCalledWith(methodArg);
      45 |     // expect(mockDynamo.queryPipelineEvents).toBeCalledWith(methodArg);
    > 46 |     expect(mockDynamo.mock.instances[0].queryPipelineEvents).toBeCalledWith(methodArg);
         |                                                              ^
      47 | 
      48 |     // Test #3: confirm the result is what we expect
      49 |     expect(actualResult).resolves.toEqual(mockQueryResult);

有人可以帮助我了解如何确认模拟方法的参数符合预期吗?

【问题讨论】:

    标签: typescript unit-testing jestjs mocking


    【解决方案1】:

    一位同事正在做不同的测试,并偶然发现了这个问题的答案。关键是将模拟方法分配给被模拟的对象和方法。去掉原始代码中的所有嘲笑,并用以下代码替换它:

    jest.mock('../../../../workflows/dynamoworkflow');
    const mockMethod = jest.fn();
    mockMethod.mockReturnValue(Promise.resolve(mockQueryResult));
    DynamoWorkflow.prototype.queryPipelineEvents = mockMethod; //<- key here!
    

    这是完整的工作测试:

    describe("PipelineService", () => {
    
      it("getCoverageByServiceName returns same data as db supplies", () => {
        //setup mock data...
        const mockPipelineEvent: PipelineEvent = new PipelineEvent();
        mockPipelineEvent.aut = "fake data";
        const mockPipelineEvents: PipelineEvent[] = [mockPipelineEvent];
        const mockQueryResult = {results: mockPipelineEvents, total: 1};
    
        //setup mock...
        jest.mock('../../../../workflows/dynamoworkflow');
        const mockMethod = jest.fn();
        mockMethod.mockReturnValue(Promise.resolve(mockQueryResult));
        DynamoWorkflow.prototype.queryPipelineEvents = mockMethod;
    
        //exercise the method we're testing...
        const methodArg = "foo-service";
        const serviceUnderTest = new PipelineService();
        const actualResult = serviceUnderTest.getCoverageByServiceName(methodArg);
    
        // and test...
        expect(mockMethod).toHaveBeenCalledWith(methodArg);
        expect(actualResult).resolves.toEqual(mockQueryResult);
      });
    
    })
    

    【讨论】:

      猜你喜欢
      • 2021-07-11
      • 2018-07-24
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多