如何解决Nest.js Jest无法模拟测试应用程序,但可以模拟测试控制器
我有一个Jest nest.js控制器测试,可以在其中测试对实时数据库的调用。很好。
我想使用嵌套HTTP Server进行“存根e2e”测试(我正在使用supertest)。但是,当我导入AppModule
时,似乎无法开玩笑来覆盖任何内容。
这是我使用存根类的工作控制器设置。
describe('Working stubbed controller test',() => {
let controller;
beforeAll(async () => {
const moduleFixture = await Test.createTestingModule({
controllers: [MyController],providers: [
{
provide: ObjectInjectionDependency,useClass: ObjectInjectionDependency
},{
provide: '@string/injection/dependency',useClass: DbOjectMockIAmUsing
},{
provide: '@another/string/injection/dependency',useValue: '@another/string/injection/dependency',},{
provide: DbConnection,useValue: {
selectOne: () => null,selectAll: () => null
}
}
]
})
.compile();
controller = moduleFixture.get<MyController>(MyController)
});
it('/GET url',async () => {
const request = {
method: "GET",params: {},query: {}
}
expect(
await controller.all(request)
).toHaveProperty(
'data'
)
});
});
这是我尝试使用supertest
将存根类与HTTP服务器结合在一起的尝试,但未成功。存根类将被忽略。
describe('Bypassing stubs application test',() => {
let app;
let server;
beforeAll(async () => {
const moduleFixture = await Test.createTestingModule({
imports: [AppModule],selectAll: () => null
}
}
]
})
.compile();
app = moduleFixture.createnestApplication();
server = app.getHttpServer()
await app.init();
});
it('/GET roots',async () => {
expect(
await request(server).get('/myEndpoint')
).toMatchObject({
'statusCode': 200
})
});
});
我尝试使用overrideProvider()
方法,但它们也不起作用
const moduleFixture = await Test.createTestingModule({
imports: [AppModule]
})
.overrideProvider(ObjectInjectionDependency)
.useClass(ObjectInjectionDependency)
.overrideProvider('@string/injection/dependency')
.useClass(DbOjectMockIAmUsing)
.overrideProvider('@another/string/injection/dependency')
.useValue('@another/string/injection/dependency')
.overrideProvider(DbConnection)
.useValue({
selectOne: () => null,selectAll: () => null
})
.compile()
我还尝试使用Jest覆盖类
Jest.mock('@path/to/dbconnection',() => {
selectOne: () => null,selectAll: () => null
}))
一切似乎都没有效果。
我尝试了spyOn()
jest.spyOn(DbConnection,'selectOne').mockImplementation(() => null);
jest.spyOn(DbConnection,'selectAll').mockImplementation(() => null);
No overload matches this call.
Overload 1 of 4,'(object: typeof DbConnection,method: never): SpyInstance<never,never>',gave the following error.
Argument of type 'string' is not assignable to parameter of type 'never'.
Overload 2 of 4,gave the following error.
Argument of type 'string' is not assignable to parameter of type 'never'.ts(2769)
我了解对控制器的测试“足够好”,但是我仍然对自己做错了事感到好奇,因为我确信将来会找到这种测试方法的用例。
编辑:
事实证明,我遇到了两个问题。首先,无论出于什么原因,我都在努力让Jest模拟类的方法。按照@Estus Flask的建议,我现在至少可以使用模拟/存根方法
import { DbConnection } from '@some/path';
jest.spyOn(DbConnection.prototype,'selectOne').mockReturnValue(null);
第二,几乎所有教程都解释了如何使用显式导入路径进行模拟
import { DbConnection } from '@some/path';
jest.mock('@some/path');
DbConnection.mockReturnValue(null);
省略了有关I discovered from this answer会引起问题的打字稿类型检查的详细信息。
let myMock = <jest.Mock<DbConnection>>DbConnection;
尽管上述初始错误有所不同,但链接答案中的类型转换和示例解决了很多困惑。
尽管如此,鉴于赏金的存在,也许有人可以解释为什么providers
数组包含import
时AppModule
数组被忽略了的原因
解决方法
对于遇到此问题的其他人,问题(至少在我的情况下)正在使用
imports: [AppModule]
据我所知,Nest在使用imports
时会自行解决所有依赖关系,并且由于AppModule
是基本上加载所有应用程序依赖关系的模块,因此无论出于何种原因,似乎所有类我在providers
数组中给出的内容将被忽略。
要解决这个问题,我只需要使用我原来的方法,但是像这样调用HTTP服务器
const response = await request(server).get('myUrl');
所以最终结构是
describe('Working stubbed controller test',() => {
let app;
let server;
beforeAll(async () => {
const moduleFixture = await Test.createTestingModule({
controllers: [MyController],providers: [
ObjectInjectionDependency,{
provide: '@string/injection/dependency',useClass: DbOjectMockIAmUsing
},{
provide: '@another/string/injection/dependency',useClass: AnotherClassIAmUsing,},{
provide: DbConnection,useValue: {
selectOne: () => null,selectAll: () => null
}
}
]
})
.compile();
app = moduleFixture.createNestApplication();
server = app.getHttpServer()
await app.init();
});
it('/GET url',async () => {
const response = await request(server).get('myUrl');
expect(response.body.data).toBe('stuff');
});
});
不包括拆卸方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。