Angular单元测试。数据服务中的可观察变量值没有更新

问题描述 投票:0回答:1

我有一个数据服务,被一个组件使用。

例如,我有一个数据服务,被一个组件使用。

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是否会自动改变。

angular unit-testing jasmine karma-jasmine angular-test
1个回答
0
投票

这就是发生的顺序。

  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) 之前,在创建组件之前。


0
投票

在创建组件之前,添加 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);
  }));

但这是一个好的做法吗.还是我应该创建一个间谍等。?

© www.soinside.com 2019 - 2024. All rights reserved.