在实际浏览器中运行Jasmine时,我注意到TestBed
fixture组件在DOM中没有被销毁,并且在测试结束后仍然存在:
这是一个经过测试的组件:
@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();
});
为什么不从DOM中移除Test
组件实例以及如何修复它?
为什么夹具组件会添加到DOM中?它们可以与AngularJS中的$rootElement
分离吗?
答案 0 :(得分:21)
我认为Angular不会自动删除它以帮助您获取有关测试执行的更多详细信息。要删除它,您只需使用afterEach:
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
comp = fixture.componentInstance;
debugElement = fixture.debugElement;
element = debugElement.nativeElement;
});
afterEach(() => {
document.body.removeChild(element);
});
答案 1 :(得分:3)
更简洁的解决方案:
afterEach(() => {
element.remove()
});
element
为fixture.debugElement.nativeElement
答案 2 :(得分:2)
请查看以下问题:
1)首先你要打电话
fixture.destroy();
afterEach ,因此在 it 部分后调用。即在它部分夹具仍然没有被销毁
2)您通过什么代码检测到DOM中仍然存在该元素?从另一个角度来看:为什么应该通过jasmine / browser删除该元素(什么原因应该使jasmine / browser)?我可以建议以下用例:
2.1)一个组件在另一个组件中使用,应该通过一些更改来创建/销毁。即 ngIf 或 ngSwitchCase :
<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 run lint的主题比单元测试(请参阅 tslint.json 中的 use-life-cycle-interface )。运行 npm run lint 后,您将看到:
Implement lifecycle hook interface OnDestroy for method ngOnDestroy in class ...
不仅错误地进行单元测试而且对tslint也没有错误,这是一个很好的做法。
答案 3 :(得分:2)
我还体验到了测试用例对DOM
所做的更改,例如:
let password = fixture.debugElement.query(By.css('input[id=password]')).nativeElement
password.value = 'somePassword';
在其他测试中持续存在。我可以使用以下afterEach
方法来解决此问题:
afterEach(() => {
TestBed.resetTestingModule();
});