【问题标题】:Angular - Jasmine test going into a loop when detectChanges is not called in the beginningAngular - Jasmine 测试在开始时未调用 detectChanges 时进入循环
【发布时间】:2019-11-14 05:35:53
【问题描述】:

我有下面的代码测试功能,按下按钮触发 ngSubmit 处理程序:

import { async, ComponentFixture, TestBed, tick, fakeAsync } from "@angular/core/testing";
import { AuthComponent } from './auth.component';
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

describe('AuthComponent', () => {
    let fixture: ComponentFixture<AuthComponent>;
    let comp: AuthComponent;
    let de: DebugElement;
    let ne: HTMLElement;
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [MatButtonModule,
                MatFormFieldModule,
                MatInputModule,
                FormsModule,
                ReactiveFormsModule, BrowserAnimationsModule],
            providers: [],
            declarations: [AuthComponent]
        }).compileComponents();
        fixture = TestBed.createComponent(AuthComponent);
        de = fixture.debugElement;
        comp = fixture.componentInstance;
        ne = de.nativeElement;
    }));
 

    it('is expected to have the button press trigger onLogin', fakeAsync(() => {

        let button = de.query(By.css('button[name=login]'));
        // let form = de.query(By.css('form'));
        fixture.detectChanges();
        spyOn(comp, 'onLogin');

        //form.triggerEventHandler('submit', null);
        button.nativeElement.click();                
        tick();
        fixture.detectChanges();

        expect(comp.onLogin).toHaveBeenCalled();        

    }));
});
<h1 class="title">Please Login</h1>

<form class="form" [formGroup]="loginForm" (ngSubmit)="onLogin()">
    <mat-form-field class="form__field">
            <input matInput type="text" name="username" placeholder="Username" formControlName="username"/>
    </mat-form-field>
    <mat-form-field class="form__field">
            <input matInput type="text" name="pass" placeholder="Password" formControlName="pass"/>
    </mat-form-field>
    <button class="form__submit" color="primary" name="login" mat-raised-button type="submit">Login</button>
</form>

下面是组件的TS代码

import { Component } from '@angular/core';
import {
    FormBuilder,
    FormControl,
    FormGroup,
    FormGroupDirective,
    Validators,
    ValidationErrors
} from '@angular/forms';

@Component({
    selector: 'sen-auth',
    templateUrl: './auth.component.html',
    styleUrls: ['./auth.component.scss']
})

export class AuthComponent {
    readonly loginForm: FormGroup;
    constructor(fb: FormBuilder) {
        this.loginForm = fb.group({ username: [], pass: [] })
    }
    public onLogin(): void {
        console.log('onLogin called');
        // if (this.loginForm.valid) {

        // }
    }
}

当测试有第一个fixture.detectChanges 调用它通过。如果将其删除,我们将进入一个循环,我认为这是由 Jasmine 未拦截表单提交引起的。有人能解释一下第一个detectChanges 电话在做什么吗?

谢谢

【问题讨论】:

    标签: angular jasmine


    【解决方案1】:

    为快速起见,请参阅fixture.detectChanges 作为更新 DOM 以进行测试的方法。如果没有,您的测试就没有填充的 DOM。

    通过使用ATB 和fixture,我们可以通过fixture.debugElement 检查组件视图,还可以通过调用fixture.detectChanges() 触发更改检测运行。 source

    更好的顺序是:

    it('is expected to have the button press trigger onLogin', () => {
       spyOn(comp, 'onLogin');
       fixture.detectChanges();
    
       let button = de.query(By.css('button[name=login]'));
    
       button.nativeElement.click();                
    
       fixture.detectChanges(); // Properties inside your component have probably changed. We need to update the DOM to see it.
    
       expect(comp.onLogin).toHaveBeenCalled();        
    
    }));
    

    【讨论】:

    • 这并没有回答为什么删除第一个调用会导致测试循环运行的问题。
    猜你喜欢
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多