【发布时间】:2018-05-24 14:35:15
【问题描述】:
我正在尝试测试一个 Angular Component,它基本上接收一个 Observable 并根据从该 Observable 发出的值更改其 template。这是一个简化版:
@Component({
selector: 'async-text',
template: `
<span>{{ text | async }}</span>
`,
})
export class AsyncTextComponent {
@Input() text: Observable<string>;
}
我想测试一下,目前这就是我所拥有的,使用rxjs-marbles(虽然不是必须的)。
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AsyncTextComponent } from './async-text.component';
describe('AsyncTextComponent', () => {
let component: BannerComponent;
let fixture: AsyncTextComponent<AsyncTextComponent>;
it('...',
marbles(m => {
fixture = TestBed.createComponent(AsyncTextComponent);
component = fixture.componentInstance;
component.text = m.cold('-a-b-c|', {
a: 'first',
b: 'second',
c: 'third',
});
fixture.detectChanges();
expect(component.nativeElement.innerHTML).toContain('first');
fixture.detectChanges();
expect(component.nativeElement.innerHTML).toContain('second');
fixture.detectChanges();
expect(component.nativeElement.innerHTML).toContain('third');
})
);
});
显然这行不通。我的问题是我没有找到一种方法在每个 expect 之间将 TestScheduler 推进给定数量的“帧”。
如何手动跳帧?或者,是否有更好的方法来测试上述组件/场景(接收 Observable 的 Angular 组件,我想根据 Observable 的发射测试它的行为)。
我确实看到了.flush(),但据记录,它运行所有 Observable 的发射,所以我会到达最终状态,并且无法测试状态之间的不同转换。
谢谢
【问题讨论】:
-
你不应该将 observable 作为输入传递
-
去掉复杂性,在父组件中使用异步管道
-
以上是简化的组件。实际上,它不仅仅是显示传入的文本,而是接收
Observable<Flag>,并根据发出的Flag的值显示不同的模板。例如,Flag.Loading将显示一个加载指示器,当发出Flag.Complete时,会显示另一个模板。 -
好的。不会改变调用子组件时应该在父组件上使用异步的事实,因此它只获取值。
-
我原则上同意,但实际上这会增加围绕该组件的样板文件,因为您必须将引发错误或完成的
Observable转换为其中一个Flags,然后才可以通过它。
标签: angular rxjs angular-test rxjs6