2017-04-26 23 views
16

当真正的浏览器运行的茉莉花我注意到,TestBed灯具组件未在DOM破坏,仍然存在测试已经结束之后:角4夹具元件坚持DOM期间茉莉花测试

enter image description here

这里有一个测试组件:

@Component({ 
    selector: 'test-app', 
    template: `<div>Test</div>`, 
}) 
class 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(); 
    }); 

为什么Test组件实例未从DOM删除,这个应该怎么定?

为什么夹具组件添加到DOM中呢?它们可以从AngularJS中的$rootElement这样的DOM中分离出来吗?

回答

14

我认为Angular不会自动将其删除,以帮助您获得有关您的测试执行的更多细节。要删除它,你只需使用afterEach:

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

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

谢谢,回答的问题之一,*应如何固定*的问题,其余的仍然适用 – estus

2

请在下面的问题就来看看:

1)首先你在afterEach调用

fixture.destroy(); 

中,所以它的在之后调用部分。即在部分夹具仍然没有销毁

2)通过什么代码你检测到该元素仍然存在于DOM?从另一个角度来看:为什么这个元素应该被茉莉花/浏览器去除(理由应该是茉莉花/浏览器)?我可以建议以下用例:

2.1)一个组件在另一个组件中使用,应该通过一些更改创建/销毁。即ngIfngSwitchCase

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

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

2.2)路由被改变(但它不是用于单元测试AFAIK)

3)当前代码接收的对象仅引用DOM元素一次。应该是这样的:

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

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

4)如果你正在努力寻找像ngOnDestroy()定义,但器具的OnDestroy没有使用,那么它的多为NPM运行皮棉比为主体错误单元测试(请看使用生命周期界面tslint.json)。运行NPM运行皮棉后只会看到:

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

这是一个很好的做法没有错误不仅为单元测试,但对于tslint了。

+0

*通过什么样的代码,你发现这个元素?仍然存在于DOM *中 - 我亲眼所见。你可以在问题中发表的一篇文章中看到这一点。 *什么原因应该使茉莉花/浏览器* - 因为我们可以。这是茉莉花的核心特征之一。而Angular以毫无理由的方式毁掉了这份报告。我想知道为什么是这样,考虑到它在AngularJS中可以。我相信OP末尾的问题是足够具体的。 – estus

+0

@estus它可能是某种回归。需要更多的调查。以下网址可能会对您有所帮助:https://github.com/angular/angular/issues/8458 – marbug

+0

谢谢。看起来很久以前它已经修复了。我认为这与TestBed的工作方式有关,很可能这是默认情况下的工作方式。只是不知道为什么,以及如何可能改变这一点。 – estus

2

一个更简洁的解决方案:

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