I've created a service, and the module for it looks like this:
launchdarkly.module.ts
@Module({
providers: [LaunchdarklyService],
exports: [LaunchdarklyService],
imports: [ConfigService],
})
export class LaunchdarklyModule {}
(this service/module is to let the application use LaunchDarkly feature-flagging)
I'm happy to show the service-implementation if you'd like, but to keep this question shorter I skipped it. The important point is that this service imports the ConfigService
(which it uses to grab the LaunchDarkly SDK key).
But how can I test the Launchdarkly
service? It reads a key from ConfigService
so I want to write tests where ConfigService
has various values, but after hours of trying I can't figure out how to configure ConfigService
in a test.
Here's the test:
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();
});
})
I'm open for any non-hacky suggestions, I just want to feature-flag my application!
Assuming the LaunchdarklyService
needs the ConfigService
and that is injected into the constructor, you can provide a mock variation of the ConfigService
by using a Custom Provider
to give back the custom credentials you need. For example, a mock for your test could look like
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();
});
})
Instead of providing ConfigService you need to import the ConfigModule with mocked data. As an example
imports: [CommonModule,ConfigModule.forRoot({
ignoreEnvVars: true,
ignoreEnvFile: true,
load: [() => ({ IntersectionOptions: { number_of_decimal_places: '3' }})],
})],
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With