Vah*_*afi 9 unit-testing nestjs nestjs-testing
我在 NestJS 中看到两种模拟服务进行单元测试的方法,第一种与我们在实际模块中定义提供程序相同,例如:
const module = await Test.createTestingModule({
providers: [
UserService,
{
provide: getRepositoryToken(User),
useValue: mockUsersRepository,
}
],
}).compile();
Run Code Online (Sandbox Code Playgroud)
以及方法的另一种方式overrideProvider。如下:
const module = await Test.createTestingModule({
imports: [UserModule]
})
.overrideProvider(getRepositoryToken(User))
.useValue(mockUsersRepository)
.compile();
Run Code Online (Sandbox Code Playgroud)
有什么不同?
因此,让我尝试这样解释它:
overrideProvider当您导入整个模块并需要覆盖它作为提供者的某些内容时,它很有用。就像提到的答案一样,用例将覆盖记录器。所以说你有
const modRef = await Test.createTestingModule({
import: [AuthModule]
}).compile();
Run Code Online (Sandbox Code Playgroud)
并假设AuthModule有imports: [ LoggerModule ]. 在我们的测试中,我们并不真的希望看到创建的所有日志,但我们无法为 提供自定义提供程序,因为LoggerService它是通过 导入和使用的LoggerModule(覆盖注入令牌并不是真正常见的做法)。因此,为了提供我们自己的实现LoggerService(假设我们只需要一个 nooplog方法),我们可以执行以下操作
const modRef = await Test.createTestingModule({
import: [AuthModule]
})
.overrideProvider(LoggerService)
.useValue({ log: () => { /* noop */ } })
.compile();
Run Code Online (Sandbox Code Playgroud)
现在,当我们AuthService调用时this.logger.log(),它只会调用它noop并完成它。
另一方面,如果我们正在进行单元测试,通常您不需要这样做,因为您只需直接在测试模块的元数据中overrideProvider设置自定义提供程序并使用它。provider
当您必须使用(例如集成和 e2e 测试)时,这overrideProvider确实很有用,否则,通常最好使用自定义提供程序imports
区别很简单。
使用第一种方法(提供程序数组),您可以创建自定义测试模块来测试(可能)UserService.
使用第二种方法,您可以使用与应用程序本身中使用的形状完全相同的完整模块。
结果是完全相同的 - 你的模拟被注入到 的构造函数中UserService。
第一种方法更适合小型的、主要是单元测试,但这些测试也可以在根本不使用 NestJS 测试工具的情况下完成(只需将模拟手动传递给 ctor),而第二种方法在集成测试中做得很好。
存储库并不是用来解释的好例子,但请考虑一下Logger。您正在执行 2 个或更多模块的一些集成测试。您不想手动创建大型测试模块(这也会破坏与模块实际形状的连接),但您只想导入正在一起测试的模块,例如,它可以让您.overrideProvider断言所有记录器调用跨所有测试的模块。LoggerloggerMock
例子:
@Module({providers: [LoggerService], exports: [LoggerService]})
export class LoggerModule {}
@Module({imports: [LoggerModule], providers: [FooService]})
export class FooModule {}
@Module({imports: [LoggerModule], providers: [BarService]})
export class BarModule {}
@Module({imports: [FooModule, BarModule]}
export class AppModule {}
// TEST
const testModule = await Test.createTestingModule({
import: [AppModule]
})
.overrideProvider(LoggerService)
.useValue(/* your logger mock will be provided in both FooService and BarService and you can easily test all related to logs then */)
.compile();
Run Code Online (Sandbox Code Playgroud)
我希望这是清楚的。如果没有,请发表评论,我会尽力解释更多。
| 归档时间: |
|
| 查看次数: |
6060 次 |
| 最近记录: |