.detectChanges()在Angular测试中不起作用 [英] .detectChanges() not working within Angular test

查看:358
本文介绍了.detectChanges()在Angular测试中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的任务是为使用Angular开发的聊天应用编写测试.以下是我目前正在为其编写测试的Angular模板代码段:

I've been tasked with writing tests for a chat app developed with Angular. Below is the snippet of Angular template code I'm currently writing tests for:

<div class="title-menu-container" fxLayoutAlign="center center">
  <button id="save-title-button" mat-icon-button *ngIf="titleInputEdit; else settings">
    <mat-icon class="secondary-text" (click)="saveTitle(titleInput.value)">check</mat-icon>
  </button>
  <ng-template #settings>
    <button mat-icon-button [matMenuTriggerFor]="menu" [disabled]="!(isGroupConversation$ | async)">
      <mat-icon class="secondary-text">settings</mat-icon>
    </button>
  </ng-template>
</div>

本质上,如果组件布尔变量'titleInputEdit'为true,则显示save-title-button,否则显示设置按钮.这是引起问题的测试用例:

Essentially, if the component boolean variable 'titleInputEdit' is true, the save-title-button is displayed, otherwise the settings button is displayed. Here is the test case that is causing problems:

it('save title button should be present', () => {
  component.titleInputEdit = true;
  fixture.detectChanges();
  expect(fixture.nativeElement.querySelector('#save-title-button')).not.toBe(null);
}); 

我只是简单地模拟"组件变量,调用.detectChanges(),然后测试按钮的存在.但是,测试失败并显示"Expected null not null".

I simply "mock" the component variable, call .detectChanges(), and then test for the presence of the button. However, the test fails with 'Expected null not to be null.'

通过各种console.log调用,我已经确认component.titleInputEdit正确设置为true,但是Fixture.nativeElement不包含正确的按钮.

Through various console.log calls, I have confirmed that the component.titleInputEdit is correctly set to true but the fixture.nativeElement DOES NOT contain the correct button.

我注意到的一些事情

  • 如果我将"component.titleInputEdit = true"行移到我的beforeEach中并将其删除,并从我的测试中调用detectChanges(),则测试通过.

  • If I move the 'component.titleInputEdit = true' line into my beforeEach and remove it, and the detectChanges() call, from my test, the test passes.

beforeEach(() => {
  fixture = TestBed.createComponent(TestComponent);
  component = fixture.componentInstance;
  component.titleInputEdit = true
  fixture.detectChanges();
  debugElement = fixture.debugElement;
});     

it('save title button should be present', () => {
    expect(fixture.nativeElement.querySelector('#save-title-button')).not.toBe(null);
});

  • 如果我从beforeEach()中删除.detectChanges()调用,并将其留在测试用例中,则测试通过.

  • If I remove the .detectChanges() call from beforeEach(), and leave it in the test case, the test passes.

    我对Angular还是比较陌生,但是我发现存在类似问题的人的实例.在尝试了那些帖子中推荐的一些东西之后,我仍然摸不着头脑.甚至更奇怪的是,我已经为其他Angular组件编写了测试,这些测试几乎可以完全相同地完成任务.

    I'm relatively new to Angular, but I've found instances of people with a similar issue. After trying some of the things recommended in those posts I'm still left scratching my head. What's even stranger is that I have written tests for other Angular components that do almost the exact same thing with no issue.

    Angular文档中提供的示例也显示了非常相似的内容:

    The example provided in the Angular docs show something very similar as well:

    it('should display a different test title', () => {
      component.title = 'Test Title';
      fixture.detectChanges();
      expect(h1.textContent).toContain('Test Title');
    });    
    

    推荐答案

    事实证明,这是由于在组件中使用了ChangeDetectionStrategy.OnPush引起的.使用OnPush仅允许您一次呼叫.detectChanges(),因此后续呼叫将无能为力.我对Angular不够熟悉,无法完全理解为什么.

    It turns out this is due to using ChangeDetectionStrategy.OnPush in the component. Using OnPush only allows you to call .detectChanges() one time, so subsequent calls will fail to do anything. I'm not familiar enough with Angular to fully understand why.

    我可以通过覆盖TestBed配置中的ChangeDetectionStrategy来产生所需的行为.

    I was able to produce the required behaviour by overriding the ChangeDetectionStrategy in my TestBed configuration.

    TestBed.configureTestingModule({
        imports: [],
        declarations: [TestComponent],
        providers: []
      })
        .overrideComponent(TestComponent, {
          set: { changeDetection: ChangeDetectionStrategy.Default }
        })
        .compileComponents();
    

    这篇关于.detectChanges()在Angular测试中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆