代码之家  ›  专栏  ›  技术社区  ›  Hantsy

DebugElement在我的角度测试示例中未按预期工作

  •  0
  • Hantsy  · 技术社区  · 6 年前

    我正在尝试将一些测试代码添加到 my Angular sample .

    这个 PostFormComponent input 绑定和 output 事件发射器。

    @Component({
      selector: 'app-post-form',
      templateUrl: './post-form.component.html',
      styleUrls: ['./post-form.component.css']
    })
    export class PostFormComponent implements OnInit, OnDestroy {
      @Input() post: Post = { title: '', content: '' };
      @Output() saved: EventEmitter<boolean> = new EventEmitter<boolean>();
      sub: Subscription;
    
      constructor(private postService: PostService) {}
    
      submit() {
        const _body = { title: this.post.title, content: this.post.content };
    
        if (this.post.id) {
          this.postService.updatePost(this.post.id, _body).subscribe(
            data => {
              this.saved.emit(true);
            },
            error => {
              this.saved.emit(false);
            }
          );
        } else {
          this.postService.savePost(_body).subscribe(
            data => {
              this.saved.emit(true);
            },
            error => {
              this.saved.emit(false);
            }
          );
        }
      }
    
      ngOnInit() {
        console.log('calling ngOnInit::PostFormComponent...');
      }
    
      ngOnDestroy() {
        console.log('calling ngOnDestroy::PostFormComponent...');
        if (this.sub) {
          this.sub.unsubscribe();
        }
      }
    }
    

    组件模板:

    <form id="form" #f="ngForm" name="form" class="form" (ngSubmit)="submit()">
       <p>
          <mat-form-field fxFlex>
              <input matInput
               id="title"
               name="title"
               #title="ngModel"
               [(ngModel)]="post.title"
               required/>
              <mat-error align="start" *ngIf="title.hasError('required')">
                Post Title is required
              </mat-error>
            </mat-form-field>
       </p>
      <p>
          <mat-form-field fxFlex>
              <textarea  matInput
                #content="ngModel"
                name="content"
                id="content"
                [(ngModel)]="post.content"
                rows="8"
                required
                minlength="10">
              </textarea>
              <mat-error align="start" *ngIf="content.hasError('required')">
                  Post Content is required
              </mat-error>
              <mat-error align="start" *ngIf="content.hasError('minlength')">
                At least 10 chars
              </mat-error>
          </mat-form-field>
      </p>
      <p>
          <button mat-button mat-raised-button color="primary" type="submit" [disabled]="f.invalid || f.pending">  {{'save'}}</button>
      </p>
    
    </form>
    

    我试图为这个组件添加一些测试。

    describe('Component: PostFormComponent(input & output)', () => {
      let component: PostFormComponent;
      let fixture: ComponentFixture<PostFormComponent>;
      let componentDe: DebugElement;
      let savePostSpy: jasmine.Spy;
      // Create a fake service object with spies
      const postServiceSpy = jasmine.createSpyObj('PostService', [
        'savePost',
        'updatePost'
      ]);
    
      beforeEach(() => {
        TestBed.configureTestingModule({
          imports: [BrowserAnimationsModule, SharedModule],
          declarations: [PostFormComponent],
          // provide the component-under-test and dependent service
          providers: [
            //   { provide: ComponentFixtureAutoDetect, useValue: true },
            { provide: PostService, useValue: postServiceSpy }
          ]
        }).compileComponents();
    
        fixture = TestBed.createComponent(PostFormComponent);
        component = fixture.componentInstance;
        componentDe = fixture.debugElement;
        fixture.detectChanges();
      });
    
      it('should raise `saved` event when the form is submitted (triggerEventHandler)', fakeAsync(() => {
        const formData = { title: 'Test title', content: 'Test content' };
        // trigger initial data binding
        component.post = formData;
        let saved = false;
        savePostSpy = postServiceSpy.savePost
          .withArgs(formData)
          .and.returnValue(of({}));
        // Make the spy return a synchronous Observable with the test data
        component.saved.subscribe((data: boolean) => (saved = data));
    
        // componentDe.triggerEventHandler('submit', null);
        component.submit();
        tick();
        fixture.detectChanges();
    
        expect(saved).toBeTruthy();
        expect(savePostSpy.calls.count()).toBe(1, 'savePost called');
      }));
    });
    

    componentDe.triggerEventHandler('submit', null) component.submit() 效果很好。

    2 回复  |  直到 6 年前
        1
  •  1
  •   codequiet    6 年前

    您希望触发表单上的提交事件,而不是整个组件,因此首先使用查询隔离表单元素:

    const formElement = componentDe.query(By.css('form#form'));
    formElement.triggerEventHandler('submit', null);
    
        2
  •  1
  •   Flyii    6 年前

    我认为你应该点击sumit按钮来触发事件

    let submitButtonEL: DebugElement = fixture.debugElement.query(By.css('button'));
    submitButtonEL.nativeElement.click()
    

    使用直接触发表单的submitevent form.triggerEventHandler('submit', null); 并不能真正保证有一个UI方式来触发事件。 编写一个测试,单击submitbutton,然后检查submitevent fired是否保证了它