我想测试一个 Angular 组件并将 contentChild 替换为 Mock。我遵循了本指南:https ://medium.com/angular-in-depth/angular-unit-testing-viewchild-4525e0c7b756 该指南适用于 viewChild,但我认为这也适用于内容儿童。
我的 contentChild 有一个父订阅的 Observable。如果我用真正的孩子测试代码,它就可以工作。如果我嘲笑孩子,测试就行不通。我认为我在测试中查询以发出新值的子模拟是一个不同的实例,而不是父订阅的那个。
我的父母:
@Component({
// tslint:disable-next-line:component-selector
selector: '[appParent]',
template: `
<div>
<span class="true" *ngIf="display$ | async; else other">True</span>
</div>
<ng-content></ng-content>
<ng-template #other><span class="false">False</span></ng-template>
`
})
export class ParentComponent implements AfterContentInit {
@ContentChild(ChildComponent) child!: ChildComponent;
display$: Observable<boolean>;
ngAfterContentInit(): void {
this.display$ = this.child.display$;
}
}
我的模拟:
@Component({
selector: 'app-child',
template: '',
providers: [
{
provide: ChildComponent,
useExisting: ChildStubComponent
}
]
})
export class ChildStubComponent {
displaySubject = new BehaviorSubject(false);
display$: Observable<boolean> = this.displaySubject.asObservable();
}
和测试:
describe('ParentComponentTest', () => {
@Component({
template: `
<div appParent>
<app-child></app-child>
</div>
`
})
class TestComponent {
@ViewChild(ChildStubComponent)
child!: ChildStubComponent;
}
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
TestComponent,
ChildStubComponent,
ParentComponent
]
}).compileComponents();
});
beforeEach(async () => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should find true', () => {
component.child.displaySubject.next(true);
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('.true'))).toBeTruthy();
});
});