1
votes

I try to create unit tests for my small application. I want to test a service that uses injected configurations and other services.

@Injectable()
export class AuthService {
        private readonly localUri: string;

        constructor(
            @Inject(CORE_CONFIG_TOKEN) private readonly coreConfig: ICoreConfig,
            @Inject(PROVIDER_CONFIG_TOKEN) private readonly providerConfig: IProviderConfig,
            private readonly _httpService: HttpService,
            private readonly _usersService: UsersService,
        ) {
            this.localUri = `http://${this.coreConfig.domain}:${this.coreConfig.port}`;
        }

        ...


        /**
         * Checks if a given email is already taken
         * @param email
         */
        async isEmailTaken(email: string): Promise<boolean> {
            return (await this._usersService.findUserByEmail(email)) !== undefined;
        }

        ...

I do not understand how to test this service. I don't know how to provide a correct TestModule provider for the injected configuration @Inject(CORE_CONFIG_TOKEN) private readonly coreConfig: ICoreConfig

    const testCoreConfig = '{...}'
    const module = await Test.createTestingModule({
      providers: [AuthService, {
           provide: 'CORE_CONFIG_TOKEN',
           useClass: testCoreConfig ,
      }],
    }).compile();

Also I am not sure if I would need also create the other imported services. I just would like to check if they are called. And if so return mock data. This I can do but I am stuck with the module setup.

All samples I found so far where just services with one repository. And more or less checks if the service exists. But no checks against the logic of the implementation and the connections between the classes.

I hope my question is clear Thank you

1

1 Answers

3
votes

I think you should be using the useValue property instead of useClass if you're passing an object of key values?

providers: [
    {
        provide: CORE_CONFIG_TOKEN,
        useValue: {
           domain: 'nestjs.com',
           port: 80,
        },
    },
],

There's also some documentation on creating a config provider/service on nestjs for your modules.

I've also created a nestjs-config module you can use similar to this.

@Injectable()
class TestProvider {
    constructor(private readonly @InjectConfig() config) {
        this.localUri = config.get('local.uri');
    }

@Module({
    imports: [ConfigModule.load('path/to/config/file/*.ts')],
    providers: [TestProvider],
})
export AppModule {}

//config file 'config/local.ts'
export default {
    uri: `https://${process.env.DOMAIN}:/${process.env.PORT}`,
}