在angular中,是否有方法测试.spec测试中是否存在mat错误?

在angular中,是否有方法测试.spec测试中是否存在mat错误?,angular,karma-jasmine,Angular,Karma Jasmine,在角度测试中,是否有方法测试规格测试中是否存在mat错误?这是我认为应该起作用的,但不是 describe('email control set to invalid email', () => { it('should result in email warning', () => { component.form.get('email').setValue('flo.com'); fixture.detectChanges();

在角度测试中,是否有方法测试规格测试中是否存在mat错误?这是我认为应该起作用的,但不是

describe('email control set to invalid email', () => {
      it('should result in email warning', () => {
        component.form.get('email').setValue('flo.com');
        fixture.detectChanges();
        expect(de.queryAll(By.css('#email-warning')).length).toBe(1);
      });
describe('email control set to invalid email', () => {
      it('should result in email warning', () => {
        component.form.get('email').setValue('flo@gmail.com');
        fixture.detectChanges();
        expect(de.queryAll(By.css('#email-warning')).length).toBe(0);
      });
问题在于,无论输入值是无效、flo.com还是有效,flo@gmail.com,查询数组的长度始终为1。如果我删除。。。从.html开始,则数组的长度为零

我的模板中还有其他元素,所以我特别寻找这个元素

这是我的html

<form [formGroup]="form">
  <mat-form-field>
    <input  name="email"
    formControlName="email"
    matInput
    type="email"
    placeholder="Email"
    autocomplete="off"/>
    <mat-error id="email-warning">Enter a valid email address.</mat-error>
  </mat-form-field>
在浏览器中,它工作正常,仅在电子邮件无效时显示警告。事实上,当电子邮件有效时,#email警告元素在已检查的html中不存在。这就是为什么我认为数组的长度应该是0。 我已经知道如何在量角器中测试它,e2e测试,真的只是问一下。规范测试

编辑 以下是出现错误时检查的html:

<div class="mat-form-field-subscript-wrapper ng-tns-c109-0" ng-reflect-ng-switch="error">

    <div class="ng-tns-c109-0 ng-trigger ng-trigger-transitionMessages ng-star-inserted" style="opacity: 1; transform: translateY(0%);">

        <mat-error _ngcontent-uiy-c122="" role="alert" id="email-warning" class="mat-error ng-tns-c109-0" ng-reflect-id="email-warning">Enter a valid email address.</mat-error>

    </div><!--bindings={"ng-reflect-ng-switch-case": "error"}--><!--bindings={"ng-reflect-ng-switch-case": "hint"}-->

</div>
describe('email control set to valid email', () => {
      it('should not result in email warning', async () => {
        component.form.get('email').setValue('flo@gmail.com');
        fixture.detectChanges();
        await fixture.whenStable();
        expect(fixture.debugElement.queryAll(By.css('#email-warning')).length).toBe(0);
      });
    });

在进行断言之前,可能需要等待一些异步操作

试试这个:

describe('email control set to invalid email', () => {
      it('should result in email warning', async() => {
        component.form.get('email').setValue('flo.com');
        fixture.detectChanges();
        await fixture.whenStable(); // wait for promises to complete before asserting
        expect(de.queryAll(By.css('#email-warning')).length).toBe(1);
      });
describe('email control set to invalid email', () => {
      it('should result in email warning', async() => {
        component.form.get('email').setValue('flo@gmail.com');
        fixture.detectChanges(); // wait for promises to complete before asserting
        expect(de.queryAll(By.css('#email-warning')).length).toBe(0);
      });
如果这不起作用,您可以只使用TypeScript,并确保HTML将正确运行,因为TypeScript是准确的

describe('email control set to invalid email', () => {
      it('should result in email warning', () => {
        component.form.get('email').setValue('flo.com');
        fixture.detectChanges();
        expect(component.form.controls['email'].hasError('email')).toBeTruthy();
      });
describe('email control set to invalid email', () => {
      it('should result in email warning', () => {
        component.form.get('email').setValue('flo@gmail.com');
        fixture.detectChanges();
        expect(component.form.controls['email'].hasError('email')).toBeFalsy();
      });
编辑

似乎
de
fixture.detectChanges
之前的旧引用,我想您需要一个新引用

describe('email control set to invalid email', () => {
      it('should result in email warning', async() => {
        component.form.get('email').setValue('flo.com');
        fixture.detectChanges();
        await fixture.whenStable(); // wait for promises to complete before asserting
        expect(fixture.debugElement.queryAll(By.css('#email-warning')).length).toBe(1); // grab a new reference by using `fixture.debugElement`
      });
describe('email control set to invalid email', () => {
      it('should result in email warning', async() => {
        component.form.get('email').setValue('flo@gmail.com');
        fixture.detectChanges(); 
        await fixture.whenStable();
        expect(fixture.debugElement.queryAll(By.css('#email-warning')).length).toBe(0); // grab a new reference by using fixture.debugElement
      });

只是想一想,规范测试应该是用于单元测试的,而实际上您要测试的是,您为表单字段包含的lib按照预期工作。与其尝试测试某些样式是否存在,我宁愿模拟材质ui—因为您可以确保它们已对其组件进行了详尽的测试—并测试“mat form”字段的子项是否包含您的错误以及正确的消息。@Erbsenkoenig—这一点很好。我还有其他的.spec测试来证明正确的验证器在它们相应的控件上。所以,我可以就此罢休。不过这次测试会让我感觉好多了。这将证明错误确实在我认为正确的时间出现。我可以依赖材料,但这是一个很容易添加的测试。如果可能的话,我想把它添加到规范中。PS-我正在检查是否出现了错误,而不是它的样式。嗯,这可以被认为是一种风格。谢谢,但加入等待,并没有改变结果。我有你建议的其他规格测试,但这不是我想要的。我已经编辑了我的答案(添加了编辑)。非常确定您需要一个对
fixture.debugElement
的新引用,因为它已更改。试试看。我添加了新的debugElement,但仍然没有通过。我还将async()方法移到了it行,而不是descripe行。我已经将我的测试代码复制到了问题中,这样你就可以看到我是否犯了任何错误。很抱歉,异步程序在错误的位置。那我就不确定了。没必要道歉。谢谢你的回复。这是一个很大的帮助,只是得到确认,它应该是工作。
describe('email control set to invalid email', () => {
      it('should result in email warning', () => {
        component.form.get('email').setValue('flo.com');
        fixture.detectChanges();
        expect(component.form.controls['email'].hasError('email')).toBeTruthy();
      });
describe('email control set to invalid email', () => {
      it('should result in email warning', () => {
        component.form.get('email').setValue('flo@gmail.com');
        fixture.detectChanges();
        expect(component.form.controls['email'].hasError('email')).toBeFalsy();
      });
describe('email control set to invalid email', () => {
      it('should result in email warning', async() => {
        component.form.get('email').setValue('flo.com');
        fixture.detectChanges();
        await fixture.whenStable(); // wait for promises to complete before asserting
        expect(fixture.debugElement.queryAll(By.css('#email-warning')).length).toBe(1); // grab a new reference by using `fixture.debugElement`
      });
describe('email control set to invalid email', () => {
      it('should result in email warning', async() => {
        component.form.get('email').setValue('flo@gmail.com');
        fixture.detectChanges(); 
        await fixture.whenStable();
        expect(fixture.debugElement.queryAll(By.css('#email-warning')).length).toBe(0); // grab a new reference by using fixture.debugElement
      });