如何使用 testing-library

问题描述

鉴于这个非常简单的属性指令,它所做的只是将输入的文本放入innerText

import { Directive,ElementRef,Input } from '@angular/core';

@Directive({
  selector: '[appTrivial]',})
export class TrivialDirective {
  @input() set text(value: any) {
    this.el.nativeElement.innerText = value.toString();
  }

  constructor(private el: ElementRef) { }
}

我正在尝试使用 rerender 中的 @testing-library/angular 来轻松更改输入:

import { render } from '@testing-library/angular';
import { TrivialDirective } from './trivial.directive';

describe('TrivialDirective',() => {
  it('should replace case insensitive',async () => {
    const template = `<div appTrivial text="qwe"></div>`;
    const { container,rerender,fixture } = await render(template,{ declarations: [TrivialDirective] });

    expect(container.querySelector('div[appTrivial]').textContent).toEqual('qwe');

    rerender({ template: `<div appTrivial text="rty"></div>` });
    // fixture.detectChanges();
    expect(container.querySelector('div[appTrivial]').textContent).toEqual('rty');
  });
});

第二个断言不起作用 - 有或没有 fixture.detectChanges()

那么,测试这样一个指令的正确方法是什么?特别是当您有几个输入并且您想在测试期间一次更改它们的所有值时。

解决方法

这样的事情可能会奏效:

  1. 为指令创建一个测试组件;
  2. 引导测试组件;
  3. 修改测试组件输入,并验证相应的调试元素原生元素更改;
import { Component,DebugElement } from '@angular/core';
import { ComponentFixture,TestBed,waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

@Component({
    selector: 'testing-component',template: '<div appTrivial text="{{textInput}}"></div>',})
export class TestingComponent {
    public textInput = ''
}

describe('TrivialDirective',() => {
    let component: TestingComponent;
    let fixture: ComponentFixture<TestingComponent>;
    let debugElement: DebugElement;
    let directive: TrivialDirective;

    beforeEach(
        waitForAsync(() => {
            void TestBed.configureTestingModule({
                declarations: [TestingComponent,TrivialDirective],})
                .compileComponents()
                .then(() => {
                    fixture = TestBed.createComponent(TestingComponent);
                    component = fixture.componentInstance;
                    debugElement = fixture.debugElement.query(By.directive(TrivialDirective));
                    directive = debugElement.injector.get(TrivialDirective);
                    fixture.detectChanges();
                });
        }),);

    it('testing component with the directive should compile successfully',() => {
        expect(component).toBeDefined();
        expect(directive).toBeDefined();
    });

    it('should set text',() => {
        const directiveElement = () => <HTMLElement>debugElement.nativeElement;
        expect(component.textInput).toEqual('');
        expect(directiveElement().innerText).toEqual('');
        const testInput = 'test input'; 
        component.textInput = testInput;
        fixture.detectChanges();
        expect(directiveElement().innerText).toEqual(testInput);
    });
});