node.js - 使用 Jest 模拟 TypeDI 服务

标签 node.js typescript unit-testing jestjs

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

@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,但要实例化它,我需要传递依赖项,并且该依赖项需要另一个依赖项。 我尝试这样做,它有效,但很丑:

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

当然,创建新的依赖项实例并不总是一个选项,并且当它具有许多依赖项时也绝对不是一个选项。

我认为它应该看起来更像:

const secondService = SomeMockFactory.create(SecondService);

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

const secondService = jest.genMockFromModule("path/to/second/service");

但是在尝试监视 secondaryService 方法后,TS 抛出错误,指出“someMethod”不是函数。 我错过了什么/做错了什么?除了 Jest 之外,我还需要其他库吗?

最佳答案

过了一段时间,我发现了如何使用默认的 Jest 行为来做到这一点。

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

// path/to/second/service/__mocks__/SecondService.ts
const mock = jest.fn().mockImplementation(() => ({
  async thingSecondServiceDoInFirstService(
    param: number
  ): number {
    return 1;

}));
export default mock;

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

// 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);
  }
}

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

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。

关于node.js - 使用 Jest 模拟 TypeDI 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61658973/

相关文章:

node.js - Node JS : Merge two PDF files into one using the buffer obtained by reading them

java - 单元测试 Jade

javascript - 如何测试 Angular 中嵌入的内容?

node.js - 如何使用 Sequelize 查询 WHERE "NOT NULL"AND "NOT EQUAL TO [STRING]"?

javascript - 如何在 postman 的响应中获取 "name"值

angular - textarea中的maxlength在Angular中不起作用

angular - 如何手动重新渲染组件 Angular 5

从父组件到子组件的 Angular 传递数组

python - 每个输入文件单独的测试用例?

node.js - 如何使用 Feathers 和 Sequelize 定义多对多,并在连接表中添加附加字段?