我是单元测试的新手,并且想知道我如何能够接近单元测试一个依赖于一个服务的组件,而这个服务又依赖于许多其他服务。以下是我的初始设置。
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TestComp],
providers: [TestService]
}).compileComponents();
}));
但是这样做,它无法找到它所依赖的其他服务。然后我会提供其他类似的服务。但随着这些服务使用其他服务等,它会继续增长。
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TestComp],
providers: [TestService, TestServiceDependencyService, TestServiceDependecyService2]
}).compileComponents();
}));
我使用另一个依赖服务的单元测试做的一件事就是创建一个这样的模拟服务。
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TestComponent],
}).overrideComponent(TestComponent, {
set: {
providers: [
{ provide: TestService, useClass: MockTestService},
]
}
})
.compileComponents();
}));
现在这里的模拟服务更容易,因为没有太多的功能,我能够"模拟"返回值。
在这个新组件中 - 模拟正确的返回值要困难得多。在这种情况下我该怎么做?
答案 0 :(得分:0)
这是我的方法,所以不要把我的话当作普遍的答案,而是作为一种快速简便的方法来做到这一点。
首先,让我告诉你,这是第一次,你做得很好。你是对的,你需要嘲笑你的依赖。
我所做的是创建模拟值而不是类(就像你一样)。我将它们放在一个文件中,这样无论你测试的组件是什么,每个模拟都是一样的。
以下是一个例子:
export const myMockedService = {};
正如您所做的那样,您需要提供它(运算符导入它只是稍微改变一下):
TestBed.configureTestingModule({
declarations: [TestComp],
providers: [{ provide: MyService, useValue: myMockedService }]
}).compileComponents();
现在你的服务被嘲笑了,你很高兴。
当您开始测试时,您的组件将尝试调用您的服务的某些方法。由于你的模拟没有任何东西,这会抛出错误,说方法丢失了(为了我的例子,让我们假设auth()
。
在这种情况下,您只需在模拟中添加:
export const myMockedService = {
auth: () => null
};
现在你的方法被嘲笑了!既然你要对一个组件进行测试,而不是你的服务,那么你就不需要实现一个完整的模拟,虚拟模拟会做得恰到好处。
之后,您仍会遇到一些错误,例如在HTTP调用的情况下can't subscribe to undefined
。
这是因为,正如您所看到的,该服务返回无。
我想你猜对了,但无论如何它仍然存在:
export const myMockedService = {
auth: () => Observable.of(null)
};
现在您的服务返回一个Observable!在某些情况下,特别是HTTP调用,您需要模拟返回,以便您可以测试组件中的功能。
再次:
export const myMockedService = {
auth: () => Observable.of(new User('Pickle', 'RIIIIIIIIIIICK'))
};
您现在拥有一个完全模拟的身份验证方法!
您可以导入RouterTestingModule
和HttpTestingModule
来模拟路由模块或http模块。这将清除这两个模块中有关依赖关系的每个错误。
答案 1 :(得分:-1)
就单元测试而言,你必须只测试那个特定的组件/服务文件,你必须要模拟它的任何其他依赖项,这是可行的方法。