2017-04-26 6 views
16

Wenn Jasmin in Echt Browser ausgeführt Ich bemerkte, dass TestBed Befestigungskomponente in DOM nicht zerstört wird und bleibt nach Tests beendet haben:Angular 4 Befestigungskomponente weiterhin besteht in DOM während Jasmin testet

enter image description here

Hier ist ein getestet Komponente:

@Component({ 
    selector: 'test-app', 
    template: `<div>Test</div>`, 
}) 
class Test {} 

Und ein Test (plunk).

let component; 
    let fixture; 
    let element; 

    beforeAll(() => { 
    TestBed.resetTestEnvironment(); 

    TestBed.initTestEnvironment(
     BrowserDynamicTestingModule, 
     platformBrowserDynamicTesting() 
    ); 
    }); 

    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     declarations: [Test], 
    }) 
    .compileComponents(); 

    fixture = TestBed.createComponent(Test); 
    component = fixture.componentInstance; 
    element = fixture.debugElement.query(By.css('div')).nativeElement; 

    fixture.detectChanges(); 
    }); 

    afterEach(() => { 
    fixture.destroy(); 
    }); 

    it('should compile Test',() => { 
    expect(element).toBeTruthy(); 
    }); 

Warum Test Komponenteninstanz nicht von DOM entfernt und wie dieser Fehler behoben werden sollte?

Warum werden Fixture-Komponenten zu DOM hinzugefügt? Können sie von DOM wie $rootElement in AngularJS gelöst werden?

Antwort

14

Ich denke, Angular entfernt es nicht automatisch, um Ihnen zu helfen, mehr Details über Ihre Testausführung zu erhalten. Um sie zu entfernen Sie einfach afterEach verwenden:

beforeEach(() => { 
    fixture = TestBed.createComponent(MyComponent); 
    comp = fixture.componentInstance; 
    debugElement = fixture.debugElement; 
    element = debugElement.nativeElement; 
}); 

afterEach(() => { 
    document.body.removeChild(element); 
}); 
+0

Danke, antwortet eine der Fragen, * wie dieser Fehler behoben werden soll * Der Rest der Fragen sind noch relevant – estus

2

Bitte nehmen Sie sich einen Blick auf die folgenden Fragen:

1) in erster Linie Sie

fixture.destroy(); 

in afterEach fordern, so ist es genannt nach es Abschnitt. I.e. in es Abschnitt Fixture ist immer noch nicht zerstört

2) mit welchem ​​Code erkennen Sie, dass das Element immer noch in DOM vorhanden ist? Von einem anderen Standpunkt: warum sollte dieses Element von Jasmin/Browser entfernt werden (welcher Grund sollte Jasmin/Browser machen)? Ich könnte folgende Use Cases vorschlagen:

2.1) eine Komponente wird in einer anderen verwendet und sollte durch einige Änderungen erstellt/zerstört werden. I.e. ngIf oder ngSwitchCase:

<parent-component> 
    <child-component *ngIf="someChangeInComponent1"></child-component> 
</parent-component> 

oder

<parent-component [ngSwitch]="type"> 
    <child-component *ngSwitchCase="'something'"></child-component> 
</parent-component> 

2,2) Routing geändert wird (aber es ist kein Thema für einheits Tests AFAIK)

3) aktuelle Code empfängt der Referenz auf DOM-Element nur einmal. Sollte so etwas wie:

beforeEach(() => { 
    ... 
    element = ... 
}); 

it('...',() => { 
    ... 
    fixture.detectChanges(); 
    element = ... // try to get element again <--------------------- here 
}) 

4) wenn Sie versuchen, Fehler wie ngOnDestroy zu finden() definiert, aber implementiert OnDestroy nicht verwendet wird, dann ist es mehr ein Thema für npm Lauf Flusen als für Unit-Tests (siehe Nutzung-Life-Cycle-Schnittstelle in tslint.json).siehe Nach dem Ausführennpm laufen Flusen werden Sie nur:

Implement lifecycle hook interface OnDestroy for method ngOnDestroy in class ... 

Es ist eine gute Praxis keine Fehler zu haben, nicht nur für Unit-Test, sondern für tslint auch.

+0

* mit welchem ​​Code, den Sie dieses Element erkennen Sie ist? immer noch in DOM * - mit meinen eigenen Augen. Sie können dies in einem Plunk sehen, das in der Frage gepostet wurde. * Welchen Grund sollte Jasmin/Browser * machen - weil wir es können. Es ist eine der Kernfunktionen von Jasmine. Und Angular ruiniert den Bericht ohne ersichtlichen Grund. Ich würde gerne wissen, warum das so ist, wenn man bedenkt, dass es in AngularJS in Ordnung war. Ich glaube, dass die Fragen am Ende des OP spezifisch genug sind. – estus

+0

@estus könnte es eine Art Regression sein. brauche mehr Untersuchung. Die folgende URL könnte für Sie interessant sein: https://github.com/angular/angular/issues/8458 – marbug

+0

Danke. Sieht so aus, als wäre es vor langer Zeit repariert worden. Ich denke, das hängt damit zusammen, wie TestBed funktioniert, und wahrscheinlich wird dies standardmäßig so funktionieren. Nur nicht sicher, warum, und wie dies geändert werden kann, wenn möglich. – estus

2

Eine knappe Lösung:

afterEach(() => { 
    element.remove() 
}); 
Verwandte Themen