在设置 compileComponents 变量之前 Angular2 测试 运行
Angular2 tests running before compileComponents variables are set
我在 Angular2 文本组件中遇到问题,当我尝试 运行 测试时出现以下错误运行ner:
Component: Product Component Should ensure component subscribes to service EventEmitter on instantiation
Failed: Cannot read property 'detectChanges' of undefined
TypeError: Cannot read property 'detectChanges' of undefined
Component: Product Component Should check that service getProducts is called when component getProducts is called
Failed: Cannot read property 'getProducts' of undefined
TypeError: Cannot read property 'getProducts' of undefined
这是我的测试模块:
import { ProductService } from "../../../../services/product.service";
import { TestBed, ComponentFixture, async } from "@angular/core/testing";
import { ProductComponent } from "../../../../components/catalog/products/ProductComponent";
import { HttpModule } from "@angular/http";
import { DebugElement, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import { Observable } from "rxjs/Rx";
class MockProductService {
emitter = Observable.of({});
constructor() {
}
getProducts() {
return this;
}
}
let comp: ProductComponent;
let fixture: ComponentFixture<ProductComponent>;
let de: DebugElement;
let el: HTMLElement;
describe('Component: Product Component', () => {
let mockProductService;
beforeEach(() => {
mockProductService = new MockProductService();
TestBed.configureTestingModule({
declarations: [
ProductComponent
],
providers: [
{
provide: ProductService, useValue: mockProductService
}
],
imports: [
HttpModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(ProductComponent);
comp = fixture.componentInstance;
});
});
it('Should ensure component subscribes to service EventEmitter on instantiation', () => {
// TestBed.compileComponents()
//.then(() => {
//spyOn(mockProductService, 'emitter').and.returnValue({
// subscribe: () => {}
//});
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(comp.products).toBe({});
});
//expect(mockProductService.emitter).toHaveBeenCalled();
//});
});
it('Should check that service getProducts is called when component getProducts is called', () => {
//TestBed.compileComponents()
// .then(() => {
spyOn(mockProductService, 'getProducts').and.returnValue({
subscribe: () => {}
});
comp.getProducts({});
expect(mockProductService.getProducts).toHaveBeenCalled();
// });
});
});
由于被测组件通过 class 的 templateUrl 属性 使用外部模板,我必须使用 TestBed 的 compileComponents 方法来编译此模板以备测试。正如您所看到的,这重新定义了一个承诺,然后我在回调中定义了为每个测试准备好的夹具和组件实例。因为这是在 beforeEach 中,所以每次测试都会这样做。
当我尝试从我的测试中访问夹具和组件实例时,它说它们是未定义的,这让我相信在从 compileComponents 方法返回承诺之前调用了测试。我尝试将 TestBed.CompileComponents 移动到每个测试规范中,但这也会导致错误。
谁能告诉我这里需要更改什么?
谢谢
以下两种方法我都成功使用过。要么使用 DoneFn
推迟 beforeEach
直到一切都完成:
beforeEach(done => {
mockProductService = new MockProductService();
TestBed.configureTestingModule({
...
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(ProductComponent);
comp = fixture.componentInstance;
done();
});
});
或使用async
并将beforeEach
分成两部分:
beforeEach(async(() => {
mockProductService = new MockProductService();
TestBed.configureTestingModule({
...
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProductComponent);
comp = fixture.componentInstance;
});
我在 Angular2 文本组件中遇到问题,当我尝试 运行 测试时出现以下错误运行ner:
Component: Product Component Should ensure component subscribes to service EventEmitter on instantiation
Failed: Cannot read property 'detectChanges' of undefined
TypeError: Cannot read property 'detectChanges' of undefined
Component: Product Component Should check that service getProducts is called when component getProducts is called
Failed: Cannot read property 'getProducts' of undefined
TypeError: Cannot read property 'getProducts' of undefined
这是我的测试模块:
import { ProductService } from "../../../../services/product.service";
import { TestBed, ComponentFixture, async } from "@angular/core/testing";
import { ProductComponent } from "../../../../components/catalog/products/ProductComponent";
import { HttpModule } from "@angular/http";
import { DebugElement, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import { Observable } from "rxjs/Rx";
class MockProductService {
emitter = Observable.of({});
constructor() {
}
getProducts() {
return this;
}
}
let comp: ProductComponent;
let fixture: ComponentFixture<ProductComponent>;
let de: DebugElement;
let el: HTMLElement;
describe('Component: Product Component', () => {
let mockProductService;
beforeEach(() => {
mockProductService = new MockProductService();
TestBed.configureTestingModule({
declarations: [
ProductComponent
],
providers: [
{
provide: ProductService, useValue: mockProductService
}
],
imports: [
HttpModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(ProductComponent);
comp = fixture.componentInstance;
});
});
it('Should ensure component subscribes to service EventEmitter on instantiation', () => {
// TestBed.compileComponents()
//.then(() => {
//spyOn(mockProductService, 'emitter').and.returnValue({
// subscribe: () => {}
//});
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(comp.products).toBe({});
});
//expect(mockProductService.emitter).toHaveBeenCalled();
//});
});
it('Should check that service getProducts is called when component getProducts is called', () => {
//TestBed.compileComponents()
// .then(() => {
spyOn(mockProductService, 'getProducts').and.returnValue({
subscribe: () => {}
});
comp.getProducts({});
expect(mockProductService.getProducts).toHaveBeenCalled();
// });
});
});
由于被测组件通过 class 的 templateUrl 属性 使用外部模板,我必须使用 TestBed 的 compileComponents 方法来编译此模板以备测试。正如您所看到的,这重新定义了一个承诺,然后我在回调中定义了为每个测试准备好的夹具和组件实例。因为这是在 beforeEach 中,所以每次测试都会这样做。
当我尝试从我的测试中访问夹具和组件实例时,它说它们是未定义的,这让我相信在从 compileComponents 方法返回承诺之前调用了测试。我尝试将 TestBed.CompileComponents 移动到每个测试规范中,但这也会导致错误。
谁能告诉我这里需要更改什么? 谢谢
以下两种方法我都成功使用过。要么使用 DoneFn
推迟 beforeEach
直到一切都完成:
beforeEach(done => {
mockProductService = new MockProductService();
TestBed.configureTestingModule({
...
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(ProductComponent);
comp = fixture.componentInstance;
done();
});
});
或使用async
并将beforeEach
分成两部分:
beforeEach(async(() => {
mockProductService = new MockProductService();
TestBed.configureTestingModule({
...
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProductComponent);
comp = fixture.componentInstance;
});