带有参数的 NgRx 选择器未通过单元测试
NgRx selectors with parameters are failing unit tests
我正在测试我的商店选择器函数是否在我的 ngOnInit() 方法中被正确调用,并且我的带参数的选择器测试失败我的没有参数的选择器正在通过(失败的测试在代码示例中被评论,它们是最后两个)。错误消息 Expected $[0] = Function to equal Function
对我没有帮助。一些关于为什么会发生这种情况的见解或只是 ngrx 的一般测试调试技巧将不胜感激。
如果需要更多代码,请告诉我。
Spec.ts
fdescribe('OpenOrderAddComponent', () => {
let component: OpenOrderAddComponent;
let fixture: ComponentFixture<OpenOrderAddComponent>;
const modalSpy: jasmine.Spy = jasmine.createSpyObj('ModalController', ['create']);
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [OpenOrderAddComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
provideMockStore({
initialState: INITIAL_APP_STATE()
}),
{ provide: ModalController, useValue: modalSpy },
]
}).compileComponents();
fixture = TestBed.createComponent(OpenOrderAddComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
describe('on ngOnInit', () => {
let store: any;
beforeEach(() => {
store = fixture.debugElement.injector.get(Store);
spyOn(store, 'select').and.callThrough();
component.documentId = 'fakeid';
component.ngOnInit();
fixture.detectChanges();
});
it('should call select 3 different times', () => {
expect(store.select).toHaveBeenCalledTimes(3); // succeeds
});
it('should select searched items ids', () => {
expect(store.select.calls.allArgs()[1]).toEqual([getSearchedItemsIds]) // succeeds
});
// FAILING TESTS BELOW
it('should select open order lines', () => {
expect(store.select.calls.allArgs()[2]).toEqual([getOpenOrderLines(component.documentId)])
// fails with error: Expected $[0] = Function to equal Function.
});
it('should select open order modifications', () => {
expect(store.select.calls.allArgs()[3]).toEqual([getOpenOrderModifications(component.documentId)])
// fails with error: Expected $[0] = Function to equal Function.
});
});
});
component.ts ngOnInit() 代码
ngOnInit(){
this.itemIds$ = this.store.select(getSearchedItemsIds);
this.store.select(getOpenOrderLines(this.documentId)).subscribe(openOrderLines => {...});
this.store.select(getOpenOrderModifications(this.documentId)).subscribe(orderModifications =>{...});
}
选择器
export const getSearchedItemsIds = createSelector(
selectSearch,
selectItems,
selectCartLines,
(searchState, items): string[] => {
return searchState.search
.map((itemId: string) => items[itemId].ItemID);
}
);
export const getOpenOrderLines = (documentId: string) => createSelector(
selectOpenOrderItems(documentId),
(orderItems?: OpenOrderItem[]) => {
return orderItems ? orderItems : undefined;
}
);
export const getOpenOrderModifications = (documentId: string) => createSelector(
selectOrderModifications(documentId),
(orderModifications: OpenOrderModification[]) => {
return orderModifications;
}
);
我会做这样的事情,!!放置在需要您注意的地方:
fdescribe('OpenOrderAddComponent', () => {
let component: OpenOrderAddComponent;
let fixture: ComponentFixture<OpenOrderAddComponent>;
const modalSpy: jasmine.Spy = jasmine.createSpyObj('ModalController', ['create']);
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [OpenOrderAddComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
provideMockStore({
initialState: INITIAL_APP_STATE()
}),
{ provide: ModalController, useValue: modalSpy },
]
}).compileComponents();
fixture = TestBed.createComponent(OpenOrderAddComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
describe('on ngOnInit', () => {
let store: any;
beforeEach(() => {
store = fixture.debugElement.injector.get(Store);
spyOn(store, 'select').and.callThrough();
component.documentId = 'fakeid';
// component.ngOnInit(); => No need to call `ngOnInit here, the `fixture.detechChanges() below does it for you. Calling it twice can make your assertions fail.
fixture.detectChanges();
});
it('should call select 3 different times', () => {
expect(store.select).toHaveBeenCalledTimes(3); // succeeds
});
it('should select searched items ids', () => {
expect(store.select.calls.allArgs()[1]).toEqual([getSearchedItemsIds]) // succeeds
});
// FAILING TESTS BELOW
it('should select open order lines', () => {
expect(store.select).toHaveBeenCalledWith(getOpenOrderLines(component.documentId));
// !! ^^
// fails with error: Expected $[0] = Function to equal Function.
});
it('should select open order modifications', () => {
expect(store.select).toHaveBeenCalledWith(getOpenOrderModifications(component.documentId));
// ^^
// fails with error: Expected $[0] = Function to equal Function.
});
});
});
但我不会断言 store.select
是用这个或那个参数调用的。我将测试每个 select
.
的 subscribe
块中发生的情况
我正在测试我的商店选择器函数是否在我的 ngOnInit() 方法中被正确调用,并且我的带参数的选择器测试失败我的没有参数的选择器正在通过(失败的测试在代码示例中被评论,它们是最后两个)。错误消息 Expected $[0] = Function to equal Function
对我没有帮助。一些关于为什么会发生这种情况的见解或只是 ngrx 的一般测试调试技巧将不胜感激。
如果需要更多代码,请告诉我。
Spec.ts
fdescribe('OpenOrderAddComponent', () => {
let component: OpenOrderAddComponent;
let fixture: ComponentFixture<OpenOrderAddComponent>;
const modalSpy: jasmine.Spy = jasmine.createSpyObj('ModalController', ['create']);
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [OpenOrderAddComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
provideMockStore({
initialState: INITIAL_APP_STATE()
}),
{ provide: ModalController, useValue: modalSpy },
]
}).compileComponents();
fixture = TestBed.createComponent(OpenOrderAddComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
describe('on ngOnInit', () => {
let store: any;
beforeEach(() => {
store = fixture.debugElement.injector.get(Store);
spyOn(store, 'select').and.callThrough();
component.documentId = 'fakeid';
component.ngOnInit();
fixture.detectChanges();
});
it('should call select 3 different times', () => {
expect(store.select).toHaveBeenCalledTimes(3); // succeeds
});
it('should select searched items ids', () => {
expect(store.select.calls.allArgs()[1]).toEqual([getSearchedItemsIds]) // succeeds
});
// FAILING TESTS BELOW
it('should select open order lines', () => {
expect(store.select.calls.allArgs()[2]).toEqual([getOpenOrderLines(component.documentId)])
// fails with error: Expected $[0] = Function to equal Function.
});
it('should select open order modifications', () => {
expect(store.select.calls.allArgs()[3]).toEqual([getOpenOrderModifications(component.documentId)])
// fails with error: Expected $[0] = Function to equal Function.
});
});
});
component.ts ngOnInit() 代码
ngOnInit(){
this.itemIds$ = this.store.select(getSearchedItemsIds);
this.store.select(getOpenOrderLines(this.documentId)).subscribe(openOrderLines => {...});
this.store.select(getOpenOrderModifications(this.documentId)).subscribe(orderModifications =>{...});
}
选择器
export const getSearchedItemsIds = createSelector(
selectSearch,
selectItems,
selectCartLines,
(searchState, items): string[] => {
return searchState.search
.map((itemId: string) => items[itemId].ItemID);
}
);
export const getOpenOrderLines = (documentId: string) => createSelector(
selectOpenOrderItems(documentId),
(orderItems?: OpenOrderItem[]) => {
return orderItems ? orderItems : undefined;
}
);
export const getOpenOrderModifications = (documentId: string) => createSelector(
selectOrderModifications(documentId),
(orderModifications: OpenOrderModification[]) => {
return orderModifications;
}
);
我会做这样的事情,!!放置在需要您注意的地方:
fdescribe('OpenOrderAddComponent', () => {
let component: OpenOrderAddComponent;
let fixture: ComponentFixture<OpenOrderAddComponent>;
const modalSpy: jasmine.Spy = jasmine.createSpyObj('ModalController', ['create']);
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [OpenOrderAddComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
provideMockStore({
initialState: INITIAL_APP_STATE()
}),
{ provide: ModalController, useValue: modalSpy },
]
}).compileComponents();
fixture = TestBed.createComponent(OpenOrderAddComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
describe('on ngOnInit', () => {
let store: any;
beforeEach(() => {
store = fixture.debugElement.injector.get(Store);
spyOn(store, 'select').and.callThrough();
component.documentId = 'fakeid';
// component.ngOnInit(); => No need to call `ngOnInit here, the `fixture.detechChanges() below does it for you. Calling it twice can make your assertions fail.
fixture.detectChanges();
});
it('should call select 3 different times', () => {
expect(store.select).toHaveBeenCalledTimes(3); // succeeds
});
it('should select searched items ids', () => {
expect(store.select.calls.allArgs()[1]).toEqual([getSearchedItemsIds]) // succeeds
});
// FAILING TESTS BELOW
it('should select open order lines', () => {
expect(store.select).toHaveBeenCalledWith(getOpenOrderLines(component.documentId));
// !! ^^
// fails with error: Expected $[0] = Function to equal Function.
});
it('should select open order modifications', () => {
expect(store.select).toHaveBeenCalledWith(getOpenOrderModifications(component.documentId));
// ^^
// fails with error: Expected $[0] = Function to equal Function.
});
});
});
但我不会断言 store.select
是用这个或那个参数调用的。我将测试每个 select
.
subscribe
块中发生的情况