Angular 2/Jasmine,在每个 describe/it 块内更新激活的路由参数订阅
Angular 2/Jasmine, updating an activated route params subscription within each describe/it block
给定一个订阅激活路由查询参数的简单组件 ngOnInit
:
export class FooComponent implements OnInit {
private queryParams: any;
constructor(
private activatedRoute: ActivatedRoute
) { }
ngOnInit() {
this.activatedRoute.queryParams.subscribe(params => this.queryParams = params);
}
active(foo: number): boolean {
return this.queryParams['foo'] &&
foo === +this.queryParams['foo'];
}
}
当 foo
查询参数存在且其值与提供的参数匹配时,活动函数应 return 为真。
在该组件的附带单元测试中,我想更改每个 it
块中查询参数的值,以测试查询参数不存在、匹配参数和不匹配参数。
describe('FooComponent', () => {
let component: FooComponent;
let fixture: ComponentFixture<FooComponent>;
let activatedRoute: ActivatedRoute;
class MockActivatedRoute {
queryParams = Observable.of({});
}
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [FooComponent],
providers: [
{ provide: ActivatedRoute, useClass: MockActivatedRoute }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(FooComponent);
component = fixture.componentInstance;
fixture.detectChanges();
activatedRoute = fixture.debugElement.injector.get(ActivatedRoute);
});
describe('active', () => {
it('should return false if the foo query param is not present', () => {
activatedRoute.queryParams = Observable.of({});
let result = component.active(100);
expect(result).toBe(false);
});
it('should return false if the foo query param does not match the supplied parameter', () => {
activatedRoute.queryParams = Observable.of({ foo: '500' });
let result = component.active(100);
expect(result).toBe(false);
});
it('should return true if the foo query param does not match the supplied parameter', () => {
activatedRoute.queryParams = Observable.of({ foo: '500' });
let result = component.active(500);
expect(result).toBe(true);
});
});
});
FooComponent class 的私有 queryParams 成员的值不会在每个 it
块内更新。 async
、fixture.whenStable()
、fakeAsync/tick
、
的各种方法我都试过了
如何更新每个单元测试的订阅值?
这是因为你分配了一个新的Observable,但是客户端已经订阅了第一个Observable。发生这种情况是因为在您第一次调用 fixture.detectChanges()
时调用了 ngOnInit
。如果您在 fixture.detectChanges()
之后等待调用 将新的 Observable 分配给 queryParams,那么将使用该 Observable。
另一种选择(可能是首选)是不使用 Observable,而是使用 Subject
。有了这个,您可以控制何时发出数据以及发出什么。
import { Subject } from 'rxjs/Subject'
import { fakeAsync, tick } from
class MockActivatedRoute {
queryParams = new Subject<any>();
}
let route: MockActivatedRoute;
beforeEach(() => {
/* configure */
route = <MockActivatedRoute>TestBed.get(ActivatedRoute);
})
it('', fakeAsync(() => {
route.queryParams.next(newparams); // emit something
tick(); // wait for resolution
fixture.detectChanges(); // detect changes (for ui)
expect(...)
}))
我说这个选项可能是首选,因为它允许在同一测试中发出多个值。
给定一个订阅激活路由查询参数的简单组件 ngOnInit
:
export class FooComponent implements OnInit {
private queryParams: any;
constructor(
private activatedRoute: ActivatedRoute
) { }
ngOnInit() {
this.activatedRoute.queryParams.subscribe(params => this.queryParams = params);
}
active(foo: number): boolean {
return this.queryParams['foo'] &&
foo === +this.queryParams['foo'];
}
}
当 foo
查询参数存在且其值与提供的参数匹配时,活动函数应 return 为真。
在该组件的附带单元测试中,我想更改每个 it
块中查询参数的值,以测试查询参数不存在、匹配参数和不匹配参数。
describe('FooComponent', () => {
let component: FooComponent;
let fixture: ComponentFixture<FooComponent>;
let activatedRoute: ActivatedRoute;
class MockActivatedRoute {
queryParams = Observable.of({});
}
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [FooComponent],
providers: [
{ provide: ActivatedRoute, useClass: MockActivatedRoute }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(FooComponent);
component = fixture.componentInstance;
fixture.detectChanges();
activatedRoute = fixture.debugElement.injector.get(ActivatedRoute);
});
describe('active', () => {
it('should return false if the foo query param is not present', () => {
activatedRoute.queryParams = Observable.of({});
let result = component.active(100);
expect(result).toBe(false);
});
it('should return false if the foo query param does not match the supplied parameter', () => {
activatedRoute.queryParams = Observable.of({ foo: '500' });
let result = component.active(100);
expect(result).toBe(false);
});
it('should return true if the foo query param does not match the supplied parameter', () => {
activatedRoute.queryParams = Observable.of({ foo: '500' });
let result = component.active(500);
expect(result).toBe(true);
});
});
});
FooComponent class 的私有 queryParams 成员的值不会在每个 it
块内更新。 async
、fixture.whenStable()
、fakeAsync/tick
、
如何更新每个单元测试的订阅值?
这是因为你分配了一个新的Observable,但是客户端已经订阅了第一个Observable。发生这种情况是因为在您第一次调用 fixture.detectChanges()
时调用了 ngOnInit
。如果您在 fixture.detectChanges()
之后等待调用 将新的 Observable 分配给 queryParams,那么将使用该 Observable。
另一种选择(可能是首选)是不使用 Observable,而是使用 Subject
。有了这个,您可以控制何时发出数据以及发出什么。
import { Subject } from 'rxjs/Subject'
import { fakeAsync, tick } from
class MockActivatedRoute {
queryParams = new Subject<any>();
}
let route: MockActivatedRoute;
beforeEach(() => {
/* configure */
route = <MockActivatedRoute>TestBed.get(ActivatedRoute);
})
it('', fakeAsync(() => {
route.queryParams.next(newparams); // emit something
tick(); // wait for resolution
fixture.detectChanges(); // detect changes (for ui)
expect(...)
}))
我说这个选项可能是首选,因为它允许在同一测试中发出多个值。