【问题标题】:How to test a nestjs service by passing in a ConfigService with custom values?如何通过传入具有自定义值的 ConfigService 来测试 nestjs 服务?
【发布时间】:2021-04-14 15:10:06
【问题描述】:

我创建了一个服务,它的模块如下所示:

launchdarkly.module.ts

@Module({
  providers: [LaunchdarklyService],
  exports: [LaunchdarklyService],
  imports: [ConfigService],
})
export class LaunchdarklyModule {}

(此服务/模块是让应用程序使用 LaunchDarkly 功能标记)

如果您愿意,我很乐意展示服务实现,但为了缩短这个问题,我跳过了它。重要的一点是该服务导入了ConfigService(它用于获取 LaunchDarkly SDK 密钥)。

但是如何测试Launchdarkly 服务呢?它从ConfigService 读取一个密钥,所以我想编写测试,其中ConfigService 具有各种值,但经过数小时的尝试,我无法弄清楚如何在测试中配置ConfigService

这是测试:

launchdarkly.service.spec.ts

describe('LaunchdarklyService', () => {
  let service: LaunchdarklyService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [LaunchdarklyService],
      imports: [ConfigModule],
    }).compile();

    service = module.get<LaunchdarklyService>(LaunchdarklyService);
  });

  it("should not create a client if there's no key", async () => {
    // somehow I need ConfigService to have key FOO=undefined for this test
    expect(service.client).toBeUndefined();
  });

  it("should create a client if an SDK key is specified", async () => {
    // For this test ConfigService needs to specify FOO=123
    expect(service.client).toBeDefined();
  });
})

我愿意接受任何非骇人听闻的建议,我只想对我的应用程序进行功能标记!

【问题讨论】:

    标签: typescript dependency-injection nestjs launchdarkly


    【解决方案1】:

    假设LaunchdarklyService 需要ConfigService 并且注入到构造函数中,您可以通过使用Custom Provider 提供ConfigService 的模拟变体,以返回您需要的自定义凭据。例如,您的测试模拟可能看起来像

    describe('LaunchdarklyService', () => {
      let service: LaunchdarklyService;
      let config: ConfigService;
    
      beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
          providers: [LaunchdarklyService, {
            provide: ConfigService,
            useValue: {
              get: jest.fn((key: string) => {
                // this is being super extra, in the case that you need multiple keys with the `get` method
                if (key === 'FOO') {
                  return 123;
                }
                return null;
              })
            }
          ],
        }).compile();
    
        service = module.get<LaunchdarklyService>(LaunchdarklyService);
        config = module.get<ConfigService>(ConfigService);
      });
    
      it("should not create a client if there's no key", async () => {
        // somehow I need ConfigService to have key FOO=undefined for this test
        // we can use jest spies to change the return value of a method
        jest.spyOn(config, 'get').mockReturnedValueOnce(undefined);
        expect(service.client).toBeUndefined();
      });
    
      it("should create a client if an SDK key is specified", async () => {
        // For this test ConfigService needs to specify FOO=123
        // the pre-configured mock takes care of this case
        expect(service.client).toBeDefined();
      });
    })
    

    【讨论】:

    • 谢谢! jest.spyOn(config, 'get').mockReturnValueOnce 产生 Error: Cannot spyOn on a primitive value; undefined given,但核心 useValue:{get: ... 模式有效。
    • 哎呀,忘了在beforeEach 中添加一行。我会对此进行编辑
    猜你喜欢
    • 2022-06-17
    • 2018-08-14
    • 1970-01-01
    • 2021-05-04
    • 2018-12-01
    • 2019-08-29
    • 2020-02-04
    • 2017-04-13
    相关资源
    最近更新 更多