afterEach(()=> {
Fixture.destroy();
});我目前正在尝试为基于ngrx的angular 7应用程序编写测试。问题是我的测试失败,并显示错误Uncaught TypeError: Cannot read property 'xxxx' of undefined thrown
。这是我的测试文件的样子。
explore-products.component.spec.ts
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { ExploreProductsComponent } from "./explore-products.component";
import { provideMockStore, MockStore } from "@ngrx/store/testing";
import { IAppState } from "src/app/store/state/app.state";
import { Store, StoreModule } from "@ngrx/store";
import { appReducers } from "src/app/store/reducers/app.reducer";
describe("ExploreProductsComponent", () => {
let component: ExploreProductsComponent;
let fixture: ComponentFixture<ExploreProductsComponent>;
let store: MockStore<IAppState>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ExploreProductsComponent],
providers: [provideMockStore()],
imports: [StoreModule.forRoot(appReducers)]
});
store = TestBed.get(Store);
});
beforeEach(() => {
fixture = TestBed.createComponent(ExploreProductsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
});
唯一的should create
测试引发错误。错误由selector
引发,这意味着xxxx
属性未初始化,但是我不确定如何解决。这是我的组件的样子。
explore-products.component.ts
import { Component, OnInit, OnDestroy } from "@angular/core";
import { IProduct } from "src/app/models/product";
import { environment } from "src/environments/environment";
import { selectProducts } from "../../store/selectors/product";
import { Store, select } from "@ngrx/store";
import { IAppState } from "src/app/store/state/app.state";
import { Subscription } from "rxjs";
@Component({
selector: "app-explore-products",
templateUrl: "./explore-products.component.html",
styleUrls: ["./explore-products.component.css"]
})
export class ExploreProductsComponent implements OnInit, OnDestroy {
public productsLoading = true;
public endpoint = environment.apiEndpoint;
private productsSelector = this.store.pipe(select(selectProducts));
public products: IProduct[];
private subscriptionsArr: Subscription[] = [];
constructor(private store: Store<IAppState>) {}
ngOnInit() {
this.subscriptions();
}
subscriptions() {
const subcriberProduct = this.productsSelector.subscribe(products => {
this.products = products;
if (this.products !== null) {
this.toggleLoadingSign(false);
}
});
this.subscriptionsArr.push(subcriberProduct);
}
toggleLoadingSign(toggleOption: boolean) {
this.productsLoading = toggleOption;
}
ngOnDestroy() {
for (const subscriber of this.subscriptionsArr) {
subscriber.unsubscribe();
}
}
}
请告知我是否可以提供其他信息。
更新
问题出在AppState
上。由于未初始化状态而导致错误发生,即state.xxxx
未定义,因此引发该错误。该错误有时不会随机发生。我不确定如何解决此问题。
here也提到了相同的问题。但是没有解决办法
答案 0 :(得分:4)
对我来说补充:
afterEach(() => {
fixture.destroy();
});
解决了组件的每个规范文件
。答案 1 :(得分:3)
对于我来说,在所有注入afterEach(() => { fixture.destroy(); });
的规范文件中添加此行代码provideMockStore()
可以解决此问题间歇触发的问题。
describe('Component', () => {
let component: Component;
let fixture: ComponentFixture<Component>;
beforeEach(async(() => {
const state = { featureKey: { property: value } }; // The state of your feature snippet
TestBed.configureTestingModule({
providers: [
provideMockStore({ initialState: state }),
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(Component);
component = fixture.componentInstance;
fixture.detectChanges();
});
afterEach(() => { fixture.destroy(); });
it('should create', () => {
expect(component).toBeTruthy();
});
});
答案 2 :(得分:0)
您可以尝试类似的方法。 看看我如何创建并使用了模拟存储。在代码更新的任何地方添加了单行注释(带有************):
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { ExploreProductsComponent } from "./explore-products.component";
import { provideMockStore, MockStore } from "@ngrx/store/testing";
import { IAppState } from "src/app/store/state/app.state";
import { Store, StoreModule } from "@ngrx/store";
import { appReducers } from "src/app/store/reducers/app.reducer";
describe("ExploreProductsComponent", () => {
let component: ExploreProductsComponent;
let fixture: ComponentFixture<ExploreProductsComponent>;
//Update the store def.************
let store: MockStore<any>;
beforeEach( async(() => { //*****************UPDATE
TestBed.configureTestingModule({
declarations: [ExploreProductsComponent],
providers: [provideMockStore()],
//Change to imports************
imports: [StoreModule.forRoot({})]
}).compileComponents();//*****************UPDATE
//Removed this
//store = TestBed.get(Store);************
}));//*****************UPDATE
beforeEach(() => {
fixture = TestBed.createComponent(ExploreProductsComponent);
//Get store instance************
store = fixture.debugElement.injector.get(Store);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
//Spy on store actions************
const spy = spyOn(store, 'dispatch');
//Test is store is called properly************
expect(spy).toHaveBeenCalledWith(Your params)
expect(component).toBeTruthy();
});
});