Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular .detectChanges()在角度测试范围内不工作_Angular_Testing_Jasmine - Fatal编程技术网

Angular .detectChanges()在角度测试范围内不工作

Angular .detectChanges()在角度测试范围内不工作,angular,testing,jasmine,Angular,Testing,Jasmine,我的任务是为Angular开发的聊天应用程序编写测试。下面是我目前正在编写测试的Angular模板代码片段: 检查 设置 本质上,如果组件布尔变量“titleInputIt”为真,则显示“保存标题”按钮,否则显示“设置”按钮。以下是导致问题的测试用例: it('应存在保存标题按钮',()=>{ component.titleInputIt=true; fixture.detectChanges(); expect(fixture.nativeElement.querySelector(“#保

我的任务是为Angular开发的聊天应用程序编写测试。下面是我目前正在编写测试的Angular模板代码片段:


检查
设置
本质上,如果组件布尔变量“titleInputIt”为真,则显示“保存标题”按钮,否则显示“设置”按钮。以下是导致问题的测试用例:

it('应存在保存标题按钮',()=>{
component.titleInputIt=true;
fixture.detectChanges();
expect(fixture.nativeElement.querySelector(“#保存标题按钮”).not.toBe(null);
}); 
我只是“模拟”组件变量,调用.detectChanges(),然后测试按钮是否存在。但是,测试失败,出现“预期null不为null”

通过各种console.log调用,我确认component.titleInputIt已正确设置为true,但fixture.nativeElement未包含正确的按钮

我注意到一些事情:

  • 如果我将'component.titleInputIt=true'行移到beforeach中并从测试中删除它,以及detectChanges()调用,则测试通过

    beforeach(()=>{
    fixture=TestBed.createComponent(TestComponent);
    组件=fixture.componentInstance;
    component.titleInputIt=true
    fixture.detectChanges();
    debugElement=fixture.debugElement;
    });     
    它('应存在保存标题按钮',()=>{
    expect(fixture.nativeElement.querySelector(“#保存标题按钮”).not.toBe(null);
    });
    
  • 如果我从beforeach()中删除.detectChanges()调用,并将其保留在测试用例中,则测试通过

我对棱角分明的人比较陌生,但我发现有类似问题的人。在尝试了这些帖子中推荐的一些东西后,我仍然感到有些挠头。更奇怪的是,我已经为其他角度组件编写了测试,这些组件几乎做了完全相同的事情,没有任何问题

角度文档中提供的示例也显示了非常类似的内容:

it('应显示不同的测试标题',()=>{
component.title='测试标题';
fixture.detectChanges();
expect(h1.textContent).toContain('testtitle');
});    

事实证明,这是由于在组件中使用了
ChangeDetectionStrategy.OnPush
。使用
OnPush
只允许您调用
.detectChanges()
一次,因此后续调用将无法执行任何操作。我对Angular不太熟悉,无法完全理解原因

通过在我的测试台配置中重写
ChangeDetectionStrategy
,我能够产生所需的行为

TestBed.configureTestingModule({
进口:[],
声明:[TestComponent],
提供者:[]
})
.overrideComponent(TestComponent{
集合:{changeDetection:ChangeDetectionStrategy.Default}
})
.compileComponents();
此处提供的答案解决了问题。然而,我认为还有另一种方法可以防止UI上出现进一步的问题。我遇到的问题与问题中描述的问题类似,这意味着在HTML上测试特定字符串时,我找不到它。即使在运行代码时,它的措辞很好,但在测试它时,UI并没有相应地更新

我要做的是:

要将
ChangeDetectorRef
注入
.ts
文件:

constructor(private changeDetector: ChangeDetectorRef) {}
并在需要时呼叫:

this.changeDetector.markForCheck();

我知道这个问题由来已久,但我最近遇到了同样的问题,一个旋转器会在业力页面上不断旋转,因为变化检测只发生一次。我的解决方法是调用fixture.detectChanges(true)还是fixture.autoDetectChanges(true)

在每个(()=>{
fixture=TestBed.createComponent(TestComponent);
组件=fixture.componentInstance;
component.titleInputIt=true
//“detectChanges”将仅测试onPush事件:
//fixture.detectChanges();
//“自动检测更改”将持续检查更改,直到测试完成。
//这比较慢,但对于某些UI更改是必需的
夹具。自动检测更改(真);
debugElement=fixture.debugElement;
}); 

在我的情况下,由于异步加载,我需要使用fixture.whenStable,而不仅仅是fixture.detectChanges,例如

it('test description', async(async () => {

    await fixture.whenStable();
}));

更好的方法是只使用
ChangeDetectionStrategy.Default
策略在规范中编写包装器组件,并通过父组件实例(即包装器组件)在规范中测试要测试的实际组件(即子组件)


通过使用
fixture.debugElement.query(by.css('your-Child-selector'))可以通过父对象的
fixture.debugElement
访问子实例及其本机元素。

对不起,答案有点误导
OnPush
策略告诉您,当其父组件更新其中一个组件输入时,仅标记组件以供检查。在测试中手动设置属性不能被Angular跟踪,因此在DOM中看不到任何更改。如果
titleInputIt
是一个输入,则在测试中创建一个主机组件,并将其属性绑定到
titleInputIt
。仅使用OnPush的
语句只允许您一次调用.detectChanges()
不是100%正确的。在这之前,应该有东西标记你的部件以供检查。这有点像是把婴儿和洗澡水一起扔掉。有很好的理由可以解释为什么您希望使用手动
detectChanges
策略,因此简单地抛弃所有这些并不是正确的解决方案。简单地将组件简化为便于测试是一个坏主意