我有一个具有编辑/新模式的组件,它根据ActivatedRoute快照参数以一种或另一种模式初始化。
正确测试它的唯一方法是在每个测试用例中为ngOnInit()调用第一个detectChanges(),然后将route.snapshot.params设置为我要测试的值。
我想知道是否有一个更优雅,更正确的解决方案。我通常更喜欢在beforeEach()方法上调用第一个detectChanges()。
我已经尝试了许多来自Internet的解决方案,但是没有一个起作用。导致我使它起作用的StackOverflow中的两个问题是:
Angular Testing, dynamically change ActivatedRoute params for different test cases
这告诉我们先调用TestBed.get(ActivatedRoute),然后设置快照参数即可,但是您必须在使用detectChanges()为ngOngInit()初始化组件之前调用它。否则快照将没有参数。
Angular 2 - test for change in route params
这讲述了使用Subject并随着参数更改发出事件。我也尝试过这个,但是不起作用。
对于这两个选项,我不得不更改组件ngOnInit()的内部实现,第一个使用快照参数,第二个使用对参数的订阅。
以下是第一个主题(1)中的解决方案,对我而言,这是适用的代码:
spec.ts
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EntryDetailComponent ],
imports: [
...
RouterTestingModule.withRoutes(testRoutes)
],
providers: [
...
{ provide: ActivatedRoute, useValue: { snapshot: { params: { 'id': null } } } }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EntryDetailComponent);
// Do this inside each test case to set
// snapshot params before init component
// fixture.detectChanges(); // ngOnInit()
component = fixture.componentInstance;
compiled = fixture.debugElement.nativeElement;
service = fixture.debugElement.injector.get(DiaryDataService);
router = TestBed.get(Router);
route = TestBed.get(ActivatedRoute);
});
it('should show \'Edit Entry\' text in edit mode', () => {
console.log('*** should show \'Edit Entry\' text in edit mode - in');
route.snapshot.params = { 'id': entryMock.id };
fixture.detectChanges(); // ngOnInit()
expect(compiled.querySelector('span').textContent.trim()).toBe('Edit Entry');
console.log('*** should show \'Edit Entry\' text in edit mode - out');
});
component.ts
ngOnInit() {
console.log('EntryDetailComponent::ngOnInit');
const params = this.route.snapshot.params;
const id = params['id'];
this.edit = (id != null);
console.log('edit = ' + this.edit);
if (this.edit) {
this.entry = this.diaryDataService.getEntry(id);
console.log(this.entry);
}
this.initForm();
}
我想知道是否有一种更优雅,更正确的方法来测试ActivatedRoute快照参数,以便在每个测试案例(1)中它们都可以不同。
此外,我想知道如何使其与params订阅一起使用,我已遵循建议的解决方案,但无法使其工作(2)。
谢谢!
package.json
"dependencies": {
"@angular/animations": "^7.0.4",
"@angular/common": "~7.0.0",
"@angular/compiler": "~7.0.0",
"@angular/core": "~7.0.0",
"@angular/forms": "~7.0.0",
"@angular/http": "~7.0.0",
"@angular/platform-browser": "~7.0.0",
"@angular/platform-browser-dynamic": "~7.0.0",
"@angular/router": "~7.0.0",
"bootstrap": "^4.3.1",
"core-js": "^2.6.5",
"dairy-client-lib": "1.0.1",
"primeicons": "^1.0.0",
"primeng": "^7.1.0",
"rxjs": "6.3.3",
"rxjs-compat": "6.3.3",
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.13.8",
"@angular/cli": "~7.0.6",
"@angular/compiler-cli": "^7.2.7",
"@angular/language-service": "~7.0.0",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^2.0.5",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "~3.1.6",
"webpack-dev-server": "^3.2.1"
}