如何解决用NestJS和异步功能开玩笑
我正在尝试在 nestJS 中测试service
的异步功能。
此函数是异步的...基本上是从数据库(使用存储库-TypeORM)获取值(JSON),并且在成功获取数据后,“转换”为另一个类(DTO)... 实现:
async getAppConfig(): Promise<ConfigAppDto> {
return this.configRepository.findOne({
key: Equal("APPLICATION"),}).then(config => {
if (config == null) {
return new class implements ConfigAppDto {
clientId = '';
clientSecret = '';
};
}
return JSON.parse(config.value) as ConfigAppDto;
});
}
使用控制器,我检查是否可以正常工作。
现在,我正在尝试使用Jest进行测试,但没有成功...
我的问题是如何从findOne
模拟repository
函数。
编辑:我正在尝试使用@golevelup/nestjs-testing
来模拟Repository
!
我已经嘲笑了repository
,但是由于某种原因,从未调用过resolve
。
describe('getAppConfig',() => {
const repo = createMock<Repository<Config>>();
beforeEach(async () => {
await Test.createTestingModule({
providers: [
ConfigService,{
provide: getRepositoryToken(Config),useValue: repo,}
],}).compile();
});
it('should return ConfigApp parameters',async () => {
const mockedConfig = new Config('APPLICATION','{"clientId": "foo","clientSecret": "bar"}');
repo.findOne.mockResolvedValue(mockedConfig);
expect(await repo.findOne()).toEqual(mockedConfig); // ok
const expectedReturn = new class implements ConfigAppDto {
clientId = 'foo';
clientSecret = 'bar';
};
expect(await service.getAppConfig()).toEqual(expectedReturn);
// jest documentation about async -> https://jestjs.io/docs/en/asynchronous
// return expect(service.getAppConfig()).resolves.toBe(expectedReturn);
});
})
-
expect(await repo.findOne()).toEqual(mockedConfig);
很好用 -
expect(await service.getAppConfig()).toEqual(expectedReturn);
超时=>Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout
;
使用调试,我看到service.getAppConfig()
也被调用了repository.findOne()
,但是findOne仓库的.then
从未被调用。
更新:我正在尝试使用@golevelup/nestjs-testing
模拟存储库,由于某种原因,模拟结果在服务中不起作用。
如果我仅使用jest
(如下面的代码)模拟存储库,则该测试有效...因此,我认为我的真正问题是@golevelup/nestjs-testing
。
...
provide: getRepositoryToken(Config),useValue: {
find: jest.fn().mockResolvedValue([new Config()])
},...
解决方法
所以,我的真正问题是如何在Repository
上模拟NestJS
。
由于某些原因,当我使用@golevelup/nestjs-testing
进行模拟时,会发生奇怪的事情!
我真的没有在@golevelup/nestjs-testing
上找到关于此的很好的文档,因此,我放弃了使用它。
我对这个问题的解决方案是仅使用Jest
和NestJS
函数...结果代码为:
服务:
// i'm injecting Connection because I need for some transactions later;
constructor(@InjectRepository(Config) private readonly configRepo: Repository<Config>,private connection: Connection) {}
async getAppConfig(): Promise<ConfigApp> {
return this.configRepo.findOne({
key: Equal("APPLICATION"),}).then(config => {
if (config == null) {
return new ConfigApp();
}
return JSON.parse(config.value) as ConfigApp;
})
}
测试:
describe('getAppConfig',() => {
const configApi = new Config();
configApi.key = 'APPLICATION';
configApi.value = '{"clientId": "foo","clientSecret": "bar"}';
beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [
ConfigAppService,{
provide: getRepositoryToken(Config),useValue: {
findOne: jest.fn().mockResolvedValue(new
Config("APPLICATION",'{"clientId": "foo","clientSecret": "bar"}')),},{
provide: getConnectionToken(),useValue: {},}
],}).compile();
service = module.get<ConfigAppService>(ConfigAppService);
});
it('should return ConfigApp parameters',async () => {
const expectedValue: ConfigApp = new ConfigApp("foo","bar");
return service.getAppConfig().then(value => {
expect(value).toEqual(expectedValue);
})
});
})
一些用于此解决方案的资源: https://github.com/jmcdo29/testing-nestjs/tree/master/apps/typeorm-sample
,我认为expect(await repo.findOne()).toEqual(mockedConfig);
之所以有效是因为您对其进行了嘲笑,因此它立即返回。
对于expect(await service.getAppConfig()).toEqual(expectedReturn);
,您没有对其进行模拟,因此可能要花费更多时间,因此it
函数在Promise
完全解决之前返回。
如果嘲笑对getAppConfig()
的调用,那么从笑话文档中发布的评论应该可以解决问题。
service.getAppConfig = jest.fn(() => Promise.resolve(someFakeValue))
或
spyOn(service,'getAppConfig').and.mockReturnValue(Promise.resolve(fakeValue))
,
来自 This answer 的 @roberto-correia 让我怀疑我们使用 System.out.println(false && (true ^ true)); // false && false -> false
System.out.println((false && true) || true); // false || true -> true
包中的 createMock
的方式是否有问题。
事实证明,该方法超过执行时间的原因与 @golevelup/nestjs-testing
没有实现模拟并且不返回任何内容有关,除非被告知这样做。
为了使方法起作用,我们必须让模拟方法在测试开始时解决一些问题:
createMock
一个基本的工作解决方案:
usersRepository.findOneOrFail.mockResolvedValue({ userId: 1,email: "some-random-email@email.com" });
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。