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
は未定義です。エラーがランダムに発生しない場合があります。これを修正する方法がわかりません。
同じ問題が ここ にも記載されています。しかし、解決策はありません
このようなものを試すことができます。私がモックストアを作成して使用した方法をご覧ください。コードが更新された場所に1行コメントを追加(************を使用):
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();
});
});