我有一个数据服务,被一个组件使用。
例如,我有一个数据服务,被一个组件使用。
BookService:
...
private book: Book;
private bookSubject = new BehaviorSubject<Book>(this.book);
bookChanged = this.bookSubject.asObservable();
...
BookComponent:
...
book: Book;
ngOnInit() {
this.bookService.bookChanged.subscribe(
(book: Book) => this.book = book;
)
}
...
组件的规范(测试文件)。
describe('BookComponent', () => {
let component: BookComponent;
let fixture: ComponentFixture<BookComponent>;
let bookServiceStub: Partial<BookService>;
bookServiceStub = {
bookChanged: of({id: 123, name: 'Book 1'})
};
beforeEach(async(() => {
TestBed
.configureTestingModule({
declarations: [BookComponent],
providers: [
{provide: BookService, useValue: bookServiceStub},
...
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BookComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should change the book with a new one', fakeAsync(() => {
const newBook = {
id: 769,
name: 'Book 2'
};
bookServiceStub.bookChanged = of(newBook);
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(component.book.id).toBe(newBook.id); // FAILS (still has old value)
expect(component.book).toBe(newBook); // FAILS (still has old value)
});
}));
});
所以测试失败了,因为 "book "变量没有用新的值更新。
我在这里做错了什么?
注意:我实际上是想测试组件中的订阅是否按照预期工作!我想检查的是 "书 "这个变量是否能正常工作。
原因:我想进一步测试,当服务中的值被更新时,DOM是否会自动改变。
这就是发生的顺序。
beforeEach(() => {
fixture = TestBed.createComponent(BookComponent);
// The component is created now. So, its constructor is run and services instantiated.
// Also, ngOnInit is executed.
// ...
it('should change the book with a new one', fakeAsync(() => {
const newBook = {
id: 769,
name: 'Book 2'
};
// And now you're overwriting bookServiceStub's bookChanged property.
// The problem is, the component doesn't care at this point, it already has a subscription,
// and it's attached to the original bookChanged stream.
bookServiceStub.bookChanged = of(newBook);
如果你在这个套件中没有更多的测试要运行 (或者如果你不需要不同的内容的 bookChanged
中),您可以简单地将 bookServiceStub.bookChanged = of(newBook)
之前,在创建组件之前。
在创建组件之前,添加 component.ngOnInit();
使我的测试运行成功。
it('should change the book with a new one', fakeAsync(() => {
const newBook = {
id: 769,
name: 'Book 2'
};
bookServiceStub.bookChanged = of(newBook);
component.ngOnInit(); // ADDED HERE
fixture.detectChanges();
expect(component.book.id).toBe(newBook.id);
expect(component.book).toBe(newBook);
}));
但这是一个好的做法吗.还是我应该创建一个间谍等。?