这是测试平台的设置。模拟并提供所需的一切:
let component: PageUploadContainer;
let store;
let route;
let fixture: ComponentFixture<PageUploadContainer>;
const sanitizer = jasmine.createSpyObj('sanitizer', ['bypassSecurityTrustResourceUrl']);
sanitizer.bypassSecurityTrustResourceUrl.and.callFake(url => url);
const mockTranslate = {
instant: label => label,
};
beforeEach(() => {
store = createMockStore<AppState>(reducers);
route = new MockActivatedRoute();
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [translationModule],
declarations: [
PageUploadContainer,
MockTranslatePipe,
MockTranslateCutPipe,
],
schemas: [NO_ERRORS_SCHEMA],
providers: [
FormBuilder,
{ provide: DomSanitizer, useValue: sanitizer },
{ provide: Store, useValue: store },
{ provide: ActivatedRoute, useValue: route },
{ provide: TranslateService, useFactory: () => mockTranslate },
],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageUploadContainer);
component = fixture.componentInstance;
component.mappingTriggered$ = Observable.of(false);
});
我有以下代码,我使用testBed设置了测试:
onGoTo(uploadStep: string) {
if (uploadStep === NAVIGATION.DEFAULT) {
this.store.dispatch(new ReplaceSelectedCompanies([]));
this.companyIds$.filter(isEmpty)
.take(1)
.subscribe(() => {
this.store.dispatch(new Navigate({ direction: uploadStep}));
});
} else {
this.store.dispatch(new Navigate({ direction: uploadStep}));
}
}
还有我的测试。由于new Navigate({ direction: uploadStep})
由于其异步性质而未被调用,因此该测试失败
it('if navigation default and companyIds empty should call navigate', () => {
component.companyIds$ = Observable.of(['123', '234']);
component.onGoTo(NAVIGATION.DEFAULT);
expect(store.dispatch).toHaveBeenCalledWith(new ReplaceSelectedCompanies([]));
expect(store.dispatch).toHaveBeenCalledWith(new Navigate({ direction: NAVIGATION.DEFAULT }));
});
您能帮我测试这些方法吗?
答案 0 :(得分:0)
您可以在测试代码完全执行后通过调用done()
来创建异步Jasmine测试。您可以从测试规范中将done
函数作为参数传递,如下所示:
it('if navigation default and companyIds empty should call navigate', (done) => {
...
});
但是,当代码完全执行时,您不会在测试代码中知道。我建议从onGoTo返回一个Promise。看起来像这样:
onGoTo(uploadStep: string): Promise<void> {
if (uploadStep === NAVIGATION.DEFAULT) {
this.store.dispatch(new ReplaceSelectedCompanies([]));
return new Promise(resolve => this.companyIds$.filter(isEmpty)
.take(1)
.subscribe(() => {
this.store.dispatch(new Navigate({ direction: uploadStep}));
resolve();
}));
} else {
this.store.dispatch(new Navigate({ direction: uploadStep}));
return Promise.resolve();
}
}
然后,像这样修改测试代码:
it('if navigation default and companyIds empty should call navigate', (done) => {
component.companyIds$ = Observable.of(['123', '234']);
component.onGoTo(NAVIGATION.DEFAULT).then(() => {
expect(store.dispatch).toHaveBeenCalledWith(new ReplaceSelectedCompanies([]));
expect(store.dispatch).toHaveBeenCalledWith(new Navigate({ direction: NAVIGATION.DEFAULT }));
done()});
});
答案 1 :(得分:0)
尽管我不确定,您可能只需要导入angular提供的async
方法即可。
常规示例
it("description", async( /* function */ ));
您的代码
import { async } from "@angular/core/testing";
it('if navigation default and companyIds empty should call navigate', async(() => {
component.companyIds$ = Observable.of(['123', '234']);
component.onGoTo(NAVIGATION.DEFAULT);
expect(store.dispatch)
.toHaveBeenCalledWith(new ReplaceSelectedCompanies([]));
expect(store.dispatch)
.toHaveBeenCalledWith(new Navigate({ direction: NAVIGATION.DEFAULT }));
}));
建议
首先,我会watch this video about angular 6 asynchronous unit tests。整个单元测试系列也不错。
您有很多自定义的模拟类,因此我对此不作过多评论。我建议您使用RouterTestingModule.withRoutes({ /* test routes */ })
。 Here's another video in that series that talks about the RouterTestingModule。
然后,您总是可以得到模拟路由器,例如router = TestBed.get(Router)
或RouterTestingModule
创建的其他对象。