Unit testing 角度2单元测试-@ViewChild未定义
我正在写一个角度2单元测试。我有一个Unit testing 角度2单元测试-@ViewChild未定义,unit-testing,angular,angular2-template,ng2-bootstrap,Unit Testing,Angular,Angular2 Template,Ng2 Bootstrap,我正在写一个角度2单元测试。我有一个@ViewChild子组件,我需要在组件初始化后识别它。在本例中,它是ng2引导库中的时间选择器组件,尽管细节不重要。在IdetectChanges()之后,子组件实例仍然未定义 伪代码: @Component({ template: ` <form> <timepicker #timepickerChild [(ngModel)]
@ViewChild
子组件,我需要在组件初始化后识别它。在本例中,它是ng2引导库中的时间选择器组件,尽管细节不重要。在IdetectChanges()之后,子组件实例仍然未定义
伪代码:
@Component({
template: `
<form>
<timepicker
#timepickerChild
[(ngModel)]="myDate">
</timepicker>
</form>
`
})
export class ExampleComponent implements OnInit {
@ViewChild('timepickerChild') timepickerChild: TimepickerComponent;
public myDate = new Date();
}
// Spec
describe('Example Test', () => {
let exampleComponent: ExampleComponent;
let fixture: ComponentFixture<ExampleComponent>;
beforeEach(() => {
TestBed.configureTestingModel({
// ... whatever needs to be configured
});
fixture = TestBed.createComponent(ExampleComponent);
});
it('should recognize a timepicker'. async(() => {
fixture.detectChanges();
const timepickerChild: Timepicker = fixture.componentInstance.timepickerChild;
console.log('timepickerChild', timepickerChild)
}));
});
@组件({
模板:`
`
})
导出类ExampleComponent实现OnInit{
@ViewChild('timepickerChild')timepickerChild:TimepickerComponent;
public myDate=新日期();
}
//规格
描述('示例测试',()=>{
让exampleComponent:exampleComponent;
let夹具:组件夹具;
在每个之前(()=>{
TestBed.configureTestingModel({
//…需要配置的任何内容
});
fixture=TestBed.createComponent(例如Component);
});
它('应该识别计时器'.async(()=>{
fixture.detectChanges();
常量timepickerChild:Timepicker=fixture.componentInstance.timepickerChild;
log('timepickerChild',timepickerChild)
}));
});
在到达控制台日志之前,伪代码按预期工作。timepickerChild
未定义。为什么会发生这种情况?我认为它应该起作用。可能您忘记在配置中导入某些模块。以下是测试的完整代码:
从'@angular/core/testing'导入{TestBed,ComponentFixture,async};
从'@angular/core'导入{Component,DebugElement};
从'@angular/forms'导入{FormsModule};
从“./test.component”导入{ExampleComponent};
从“ng2引导/ng2引导”导入{TimepickerModule,TimepickerComponent};
描述('示例测试',()=>{
让exampleComponent:exampleComponent;
let夹具:组件夹具;
在每个之前(()=>{
TestBed.configureTestingModule({
导入:[FormsModule,TimepickerModule.forRoot()],
声明:[
示例组件
]
});
fixture=TestBed.createComponent(例如Component);
});
它('应该识别时间选择器'),异步(()=>{
fixture.detectChanges();
常量timepickerChild:TimepickerComponent=fixture.componentInstance.timepickerChild;
log('timepickerChild',timepickerChild);
expect(timepickerChild).tobededefined();
}));
});
在大多数情况下,只需将其添加到声明中即可
beforeEach(async(() => {
TestBed
.configureTestingModule({
imports: [],
declarations: [TimepickerComponent],
providers: [],
})
.compileComponents()
确保您的子组件没有计算为false的*ngIf。如果是这样,将导致子组件未定义 如果要使用存根子组件测试主组件,则需要向存根子组件添加提供程序;正如文章中所解释的那样
从'@angular/core'导入{Component};
从“./child.component”导入{ChildComponent};
@组成部分({
选择器:“应用程序子项”,
模板:“”,
供应商:[
{
提供:子组件,
useClass:ChildStubComponent
}
]
})
导出类组件{
updateTimeStamp(){}
}
请注意提供程序元数据,以便在需要ChildComponent时使用类ChildStubComponent
然后,您可以正常创建父组件,其子组件将使用ChildStubComponent类型创建。即使按照接受的答案中的所有内容进行操作,您仍将获得子组件的未定义实例,请检查该组件是否可见
在我的例子中,控件上应用了*ngIf
,这就是为什么child的实例没有定义,然后我删除并检查了它,它对我有效你找到答案了吗?我也有同样的问题。我有一种模糊的感觉,好像大多数选民都有不同的问题。确保您的子组件未被任何*ngIf=“false”
指令隐藏。另外,在将渲染条件设置为true
后,执行fixture.detectChanges()
,这将(重新)创建以前未定义的子组件。我认为这不是一个好的解决方案。如果您在测试中声明组件,那么您对它们有一个硬依赖关系。也就是说,如果他们(出于某种原因)停止工作,你的测试也会失败。如果我想测试主组件而不包括实际的子组件,那么你应该选择模拟组件(比如这里:),那么有没有办法模拟它们呢?@Eugene你能在stackblitz中提供一些例子吗?但是@ViewChild('timepickerChild')timepickerChild:TimepickerComponent代码>应该是私有字段。非常好,谢谢