我试图对订阅数据服务变量的组件进行单元测试。我试图模拟服务并覆盖组件的私有数据服务变量,但我不确定如何测试模拟变量的订阅。这是我的(有限)代码:
服务:
export class Service {
constructor(private dataService: DataService) {
this.dataService.newData.subscribe(data => {
//do something
});
}
}
数据服务:
export class DataService {
private source = new BehaviorSubject<any>([]);
newData = this.source.asObservable();
//code to update source
}
服务单元测试:
mockDataService {
private source = new BehaviorSubject<any>([]);
newData = this.source.asObservable();
}
describe('Service', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
Service,
{provide: DataService, useClass: mockDataService} // is this correct?
]
}).overrideComponent(Service, {
set: {
providers: [
{provide: DataService, useClass: mockDataService}
]
}
}).compileComponents();
});
it('should register subscription', inject([Service, DataService], (service: ServiceA, mock: DataService) => { //should I be injecting the mock class?
expect(before()).toBeTruthy();
mock.newData.next("test"); // what's the correct way to test?
expect(after()).toBeTruthy();
}));
}
我是否正确地覆盖?如果是这样,如何在订阅私有服务变量时正确测试我的组件是否执行了正确的操作?
谢谢!
答案 0 :(得分:1)
首先,如果您可以在类旁边提供注释,将会很有帮助。我假设Service
类是一个组件,因为你引用的是调用TestBed.overrideComponent
时。在这种情况下,命名令人困惑。它应该至少有一个后缀“Component”(参见Angular style guide。)
如果Service
实际上应该是服务类,那么将服务嵌套到另一个服务类可能不是一个好习惯(see docs。)
你基本上要求两件事。
providers
?TestBed.configureTestingModule
属性
对于上面的示例,这不是必需的。您可以轻松地从对象中省略providers属性。它看起来像
TestBed.configureTestingModule({})
在某些情况下,可能需要更改提供程序 - 但不是在您的情况下。
您似乎正在将集成测试与单元测试混合在一起。您希望以两种方式测试服务。
首先:单元测试服务(Angular docs)
第二:整合测试 - 你在这里做的事情。从文档(link)开始,建议采用最佳做法:
it('should register subscription', () => {
const fixture = TestBed.createComponent(Service);
dataService = fixture.debugElement.injector.get(DataService);
// do things
});
关于mock.newData.next("test")
,你在这里想要实现的目标并不是很清楚。此方法调用可能会给您undefined function test
错误。为什么?您指的是this.source.asObservable()
,它返回Obersvable。该对象没有next
方法。你应该做一些关于RxJs的基础教程。
希望这有帮助!
最佳, 畚箕