角度单元测试 - 如何模拟在商店调度期间由ngrx / effect调用的组件中的提供者

时间:2018-06-14 07:03:18

标签: angular ngrx ngrx-effects angular-unit-test

我有一个组件,在ngOninit中,我正在调度一个由ngrx / effect处理的动作,以从服务API获取一些数据。我正在编写单元测试,并希望在ngOninit中模拟服务调用,以便不调用原始API。但仍然调用原始API,可能是因为它是从效果处理的。我应该如何处理这个问题,以便我停止实际的API调用并调用模拟服务API?

组件代码:

ngOnInit() {
   this.sectionId$ = this.store.select(reducers.getSectionIDFromAppState).subscribe((sectionID) => {
   if (sectionID) {
     this.store.dispatch(new layoutActions.GetLogFormatListAction(sectionID));
  }
}

行动守则:

export class GetLogFormatListAction implements Action {
type = ActionTypes.GET_LOG_FORMAT_LIST;
constructor(public payload?: any) {
    this.payload = payload;
}

}

效果代码:

@Effect()
getLogFormatList$: Observable<Action> = this.actions$
    .ofType(layoutActions.ActionTypes.GET_LOG_FORMAT_LIST)
    .mergeMap((action: any) => {
        return this.layoutService.getLogFormatList(action.payload)
            .map(logFormatList => new layoutActions.GetLogFormatListSuccessAction(logFormatList))
            .catch(error => Observable.of(new layoutActions.GetLogFormatListFailureAction(error)));
    });

Layout.service.ts

getLogFormatList(sectionId): Observable<any> {
const requestData = {
  endpoint: environment.endpoints.GET_LOG_FORMAT_LIST.endpoint + sectionId,
  params: {
  }
};
return this.httpRequestWrapperService.fetchData(requestData);  }

我的规范代码:

beforeEach(async(() => {
TestBed.configureTestingModule({
  declarations: [
    LogviewerWidgetConfigComponent,
    MockComponent({ selector: 'app-logviewer-config-template', inputs: ['logformatList', 'widgetConfig' , 'index'] }),
    MockComponent({ selector: 'app-widget-config-header', inputs: ['model'], outputs: ['closeWidgetConfig'] }),
  ],
  imports: [FormsModule, StoreModule.forRoot(reducers)],
  providers: [{ provide: LayoutService, useClass: MockLayoutService }]
}).compileComponents();  }));

beforeEach(() => {
store = TestBed.get(Store);
spyOn(store, 'dispatch').and.callThrough();
fixture = TestBed.createComponent(LogviewerWidgetConfigComponent);
component = fixture.componentInstance;
fixture.detectChanges();  });

模拟服务:

class MockLayoutService {
  getLogFormatList(param: any): Observable<any> {
   return Observable.of(null);
  }
}

1 个答案:

答案 0 :(得分:0)

你没有嘲笑你的API调用,你嘲笑了另一个服务。

如果你想模拟你的API调用,请进行模拟:

const storeMock = {
  select: () => Observable.of(null),
  dispatch: () => null
};

并在你的试验台提供:

providers: [
  { provide: LayoutService, useClass: MockLayoutService },
  { provide: Store, useValue: storeMock }
]

(我不知道您正在使用的依赖项,但我认为如果您模拟其服务,可能必须从imports中删除StoreModule。

完成后,您的通话将不再是API,而是点击模拟。