【问题标题】:Jest Unit Test for Node Service having async methods具有异步方法的节点服务的 Jest 单元测试
【发布时间】:2021-10-06 23:47:45
【问题描述】:

我遇到了以下错误。为什么我收到来自服务的undefined 响应? 我提供模拟实现有什么问题吗?

服务:

export class SaveDataService{
    async save() : Promise<any> {
        try{
            return this.someFunction()
        } catch(ex){
            throw new Error('some error occured')
        }
    }

    async someFunction() : Promise<any>{
        const response = {
            "file" : "<htm><body>This is sample response</body></html>"
        }
        return Promise.resolve(response);
    }
}

测试/规格文件:

import { SaveDataService } from "./save-data.service";

jest.mock('./save-data.service')

describe('tests for SaveDataService', () => {

    it('when save method is called and success result is returned', async () => {
        let mockSaveDataServiceSomeFunction = jest.fn().mockImplementation(() => {
            return Promise.resolve('Success Result')
        }); 
        SaveDataService.prototype.someFunction = mockSaveDataServiceSomeFunction;

        let spy = jest.spyOn(SaveDataService.prototype, 'someFunction');

        let service = new SaveDataService();
        let data = await service.save()
        expect(data).toEqual('Success Result')
        expect(spy).toHaveBeenCalled()
    })

    it('when save method is called and error is returned', async () => {
        let mockSaveDataServiceSomeFunction = jest.fn().mockImplementation(() => {
            throw new Error('ERROR')
        }); 
        SaveDataService.prototype.someFunction = mockSaveDataServiceSomeFunction;

        let spy = jest.spyOn(SaveDataService.prototype, 'save');

        let service = new SaveDataService();
        service.save()
        expect(spy).toThrowError('ERROR')
    })
})

【问题讨论】:

标签: node.js typescript unit-testing jestjs jasmine


【解决方案1】:

模拟替换依赖项。您设置对依赖对象调用的期望,设置它应该为您执行所需测试提供的确切返回值,和/或抛出哪些异常,以便您可以测试异常处理代码。

在这种情况下,您通过调用 jest.mock('./save-data.service') 来模拟 save-data.service。这样您的班级可能看起来像这样:

async save() : Promise<any>  {
  // do nothing or undefined
}

async someFunction() : Promise<any>  {
  // do nothing or undefined
}

因此,您必须自己实现主体,以期待您希望方法/函数为您做什么。你只是在嘲笑someFunction:

...

let mockSaveDataServiceSomeFunction = jest.fn().mockImplementation(() => {
    return Promise.resolve('Success Result')
}); 

SaveDataService.prototype.someFunction = mockSaveDataServiceSomeFunction;

...

因此,当您调用 save() 方法时,您仍然没有得到任何/未定义的结果。

您正在覆盖服务的整个行为,我认为您的测试可能没有用。但是您可以通过这种方式修复您的测试:

import { SaveDataService } from "./save-data.service";

jest.mock('./save-data.service');

describe('tests for SaveDataService', () => {
  beforeEach(() => {
    SaveDataService.mockClear();
  });

  it('when save method is called and success result is returned', async () => {
    const spy = jest
      .spyOn(SaveDataService.prototype, 'save')
      .mockImplementation(async () => Promise.resolve('Success Result'));

    const service = new SaveDataService();
    const data = await service.save();

    expect(data).toEqual('Success Result');
    expect(spy).toHaveBeenCalled();
  })

  it('when save method is called and error is returned', async () => {
    const spy = jest
      .spyOn(SaveDataService.prototype, 'save')
      .mockImplementation(() => {
        throw new Error('ERROR');
      });

    const service = new SaveDataService();
    expect(service.save).toThrowError('ERROR');
    expect(spy).toHaveBeenCalled();
  });
});

【讨论】:

    猜你喜欢
    • 2021-10-14
    • 2020-07-14
    • 2011-11-07
    • 1970-01-01
    • 2021-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    相关资源
    最近更新 更多