我开始学习单元测试,并且了解主要目标是孤立地测试系统。因此,应该对任何依赖项进行存根,模拟等。
根据有关测试的Angular文档,您应该模拟依赖项注入提供的任何内容。到目前为止,一切都很好。但是,然后,如下面的代码所示,您只需通过共享或功能模块导入其他必需的模块,组件,指令,管道。
那么这真的是单元测试吗?如果被测目标系统是一个组件,那么这不是真的测试了整个模块吗?
或者这仅仅是在现实世界中模拟所有需求几乎是不可能的?
beforeEach(async(() => {
const routerSpy = createRouterSpy();
TestBed.configureTestingModule({
imports: [ SharedModule ],
declarations: [ HeroDetailComponent ],
providers: [
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: HeroService, useClass: TestHeroService },
{ provide: Router, useValue: routerSpy},
]
})
.compileComponents();
}));
答案 0 :(得分:2)
那么这真的是单元测试吗?如果被测目标系统是一个组件,那么这不是真的测试了整个模块吗?
单元测试的定义是测试源代码的小单元,而组件实际上是源代码的小单元。
但是,如下代码所示,您可以简单地通过共享或功能模块导入其他必需的模块,组件,指令,管道。
可以在JavaScript中进行测试的最小源代码单元是pure function。如果您是最纯洁的人,那么更大的任何单位都不再是最小的单位,但是Angular是Object Oriented框架,因此在该范式下我们可以说 object 是最小单位。因此,诸如组件,服务,激活器,解析器之类的所有对象都可以通过单元测试来覆盖。
或者这仅仅是在现实世界中模拟所有需求几乎是不可能的?
祝您在构建系统后尝试测试它。
如果您想构建可以测试的东西,请先编写测试。
https://en.wikipedia.org/wiki/Test-driven_development
一个纯组件是一个没有外部依赖的组件,它不会使外部状态发生变化,并且会为相同的输入生成相等的输出。具有用户表单的组件不可能像new Date()
不是纯净的一样纯。
单元测试框架理解这些真实世界问题,并提供模拟,间谍等解决方案,以使测试人员可以通过验证 pure期望的测试覆盖不纯的源代码。 可重复的方式。
这就是您所能做的,但这仍然是单元测试,这很重要。
答案 1 :(得分:1)
(基于大量观点,因此可以不同意)。这并不是真正针对角度的,例如,如果您正在对使用numpy的Python函数进行单元测试,您仍将numpy导入到UT中。因此,在这里您可以导入材料组件作为示例,而您并不能真正模拟它们(即使您这样做不是一个好主意,您也要确保正确使用它们)。 基本上,我会说在单元测试中您正在模拟/添加您的其他功能(此处的heroService被模拟),并且http请求响应,但是您只能假定外部库可以按预期工作,因此您仍然可以导入和使用它们
答案 2 :(得分:1)
您写
主要目标是隔离测试系统
是-否。单元测试用于发现在独立软件中发现的错误。这并不意味着您实际上必须在测试期间必须隔离代码。换句话说,您不必模拟所有依赖项。例如,如果您的代码使用sin()
函数,那么这也是对其他代码部分的依赖,但是这种依赖通常不会损害您正确测试代码的能力。
一般规则是,应出于某种原因进行模拟。充分的理由是:
您可以很容易地看到,使用sin()
函数通常不属于上述原因。您将不得不判断这是否也适用于您的方案。
但是,以上观点的一个结论是,如果不模拟所有依赖项,则还可以进行单元测试。但是-单元测试的显着特征是什么?将单元测试与例如集成测试区分开来的是您在各个测试中追求的目标。
如果您的目标是查找解决另一个组件问题的方式的错误(例如,如果以错误的顺序或错误的参数调用了另一个组件的函数,或者返回值的格式不正确等) ,那么这将不是单元测试,而是集成测试:在单独测试组件时,您甚至无法找到这些错误-您需要其他组件才能找到它们。