首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Jest模拟TypeDI服务

用Jest模拟TypeDI服务
EN

Stack Overflow用户
提问于 2020-05-07 13:27:33
回答 1查看 3.8K关注 0票数 2

我将Node与TypeScript、TypeDI和Jest结合使用。我正在创建相互依赖的服务,比方说:

代码语言:javascript
复制
@Service()
export class MainService{
constructor(private secondService: SecondService){}
public someMethod(someString: string) // implementation depends on secondService
}

@Service()
export class SecondService{
constructor(private thirdService: ThirdService){}
}

@Service()
export class ThirdService{
constructor(){}
}

我想测试MainService,但是要实例化它,我需要传递依赖项,而该依赖项需要另一个依赖项。我试过这样做,效果很好,但很丑:

代码语言:javascript
复制
const secondService = new SecondService(new ThirdService());
jest
    .spyOn(secondService, "someMethod")
    .mockImplementation((someString: string) => {
        // do something
        return something;
    });
const mainService = new MainService(secondService);
// use mainService in tests

当然,创建依赖关系的新实例并不总是一个选项,当它有许多依赖项时,它也不一定是一个选项。

我觉得应该看上去更像:

代码语言:javascript
复制
const secondService = SomeMockFactory.create(SecondService);

但是,我找不到任何方法来创建模拟,同时切断依赖关系。我试着用

代码语言:javascript
复制
const secondService = jest.genMockFromModule("path/to/second/service");

但是在尝试spyOn secondService方法之后,TS抛出了"someMethod“不是函数的错误。我错过了什么/做错了什么?除了Jest我还需要别的图书馆吗?

EN

回答 1

Stack Overflow用户

发布于 2020-10-01 08:29:38

过了一会儿,我发现了如何使用默认的玩笑行为来做到这一点。

首先,您需要在SecondService中创建path/to/second/service/__mocks__的模拟,例如:

代码语言:javascript
复制
// path/to/second/service/__mocks__/SecondService.ts
const mock = jest.fn().mockImplementation(() => ({
  async thingSecondServiceDoInFirstService(
    param: number
  ): number {
    return 1;

}));
export default mock;

SecondService必须是默认导出,例如:

代码语言:javascript
复制
// path/to/second/service/SecondService.ts
    @Service()
export default class SecondService {
constructor(private thirdService: ThirdService) {}
  async thingSecondServiceDoInFirstService(
    param: number
  ): number {
    return this.thirdService.thingThirdServiceDoInSecond(param);
  }
}

在测试文件中,您必须在jest.mock导入SecondService之前使用,然后从创建SecondService实例:

代码语言:javascript
复制
jest.mock("path/to/second/service/SecondService");
import SecondService from "path/to/second/service/SecondService";
import MainService from "path/to/main/service/MainService";

describe("Test main service", () => {

  const SecondServiceMock = <jest.Mock<SecondService>>SecondService;
  let secondService = new SecondServiceMock();

  beforeEach(() => {
    mainService = new MainService(secondService);
  });

// test logic...
}

按照要求,不再需要ThirdService了。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61658973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档