Jon*_*sen 9 dependency-injection mocking typescript jestjs nestjs
给定一个通过 @InjectQueue 装饰器使用队列的 Injectable:
@Injectable()
export class EnqueuerService {
constructor (
@InjectQueue(QUEUE_NAME) private readonly queue: Queue
) {
}
async foo () {
return this.queue.add('job')
}
}
Run Code Online (Sandbox Code Playgroud)
如何测试该服务是否正确调用队列?我可以做基础脚手架:
describe('EnqueuerService', () => {
let module: TestingModule
let enqueuerService: EnqueuerService
beforeAll(async () => {
module = await Test.createTestingModule({
imports: [EnqueuerModule]
}).compile()
enqueuerService = module.get(EnqueuerService)
// Here I'd usually pull in the dependency to test against:
// queue = module.get(QUEUE_NAME)
//
// (but this doesn't work because queue is using the @InjectQueue decorator)
})
afterAll(async () => await module.close())
describe('#foo', () => {
it('adds a job', async () => {
await enqueuerService.foo()
// Something like this would be nice:
// expect(queue.add).toBeCalledTimes(1)
//
// (but maybe there are alternative ways that are easier?)
})
})
})
Run Code Online (Sandbox Code Playgroud)
我对 Nest DI 容器设置很迷茫,但我怀疑有一些聪明的方法可以做到这一点。但尽管经过数小时的尝试,我仍无法取得进展,而且文档也没有帮助我。谁能提供解决方案吗?它不必是嘲笑,如果更容易创建一个真实的队列来测试也很好,我只想验证我的服务是否按预期排队!任何帮助表示赞赏。
Bab*_*boo 17
通过查看该库,我发现了一个辅助函数,该函数根据其名称创建队列注入令牌:getQueueToken(name?: string)。
该函数是从库中导出的,因此您可以使用它来提供自己的队列实现以进行测试。
import { getQueueToken } from '@nestjs/bull';
describe('EnqueuerService', () => {
let module: TestingModule
let enqueuerService: EnqueuerService
beforeAll(async () => {
module = await Test.createTestingModule({
imports: [EnqueuerModule]
})
.overrideProvider(getQueueToken(QUEUE_NAME))
.useValue({ /* mocked queue */ })
.compile()
enqueuerService = module.get(EnqueuerService)
queue = module.get(QUEUE_NAME)
})
afterAll(async () => await module.close())
describe('#foo', () => {
it('adds a job', async () => {
await enqueuerService.foo()
expect(queue.add).toBeCalledTimes(1)
})
})
})
Run Code Online (Sandbox Code Playgroud)
编辑
要检查队列服务调用的方法,您可以在测试文件的根目录下创建一个模拟。我重新组织了测试文件,以便在测试设置和测试本身之间有更清晰的分离:
let module: TestingModule
let enqueuerService: EnqueuerService
let mockQueue;
// Create a helper function to create the app.
const createApp = async () => {
module = await Test.createTestingModule({
imports: [EnqueuerModule]
})
.overrideProvider(getQueueToken(QUEUE_NAME))
.useValue(mockQueue)
.compile()
enqueuerService = module.get(EnqueuerService)
}
describe('EnqueuerService', () => {
// Recreate app before each test to clean the mock.
beforeEach(async () => {
mockQueue = {
add: jest.fn(),
};
await createApp();
})
afterAll(async () => await module.close())
describe('#foo', () => {
it('adds a job', async () => {
await enqueuerService.foo()
// Check calls on the mock.
expect(mockQueue.add).toBeCalledTimes(1)
})
})
describe('#bar', () => {
// Override the mock for a specific test suite.
beforeEach(async () => {
mockQueue.add = jest.fn().mockImplementation(/** */);
// The mock has changed so we need to recreate the app to use the new value.
await createApp();
})
it('adds a job', async () => {
// ...
})
})
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7731 次 |
| 最近记录: |