Angular 测试,针对不同的测试用例动态更改 ActivatedRoute 参数
Angular Testing, dynamically change ActivatedRoute params for different test cases
组件:
@Component({
selector: 'app-test',
templateUrl: './test.component.html'
})
export class TestComponent implements OnInit {
useCase: string;
constructor(
private route: ActivatedRoute,
) {}
ngOnInit() {
this.route.queryParams.subscribe(p => {
if (p) {
this.useCase = p.u;
}
});
}
}
测试规格
describe('TestComponent', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
AppModule
],
providers: [
{ provide: ActivatedRoute, useValue: ??? }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
expect(component.useCase).toBeFalsy();
});
it('should set useCase variable with query string value', () => {
fixture.detectChanges();
// Set different route.queryParams here...
expect(component.useCase).toBe('success');
});
});
使用Angular6、Karma和Jasmine进行单元测试。
我知道我们可以将 ActivatedRoute
设置为将在整个测试过程中使用的对象,例如:
providers: [
{ provide: ActivatedRoute, useValue: {
queryParams: Observable.of({id: 123})
} }
]
但这将为所有测试用例设置值。有没有办法在每个不同的测试用例中动态更改 ActivatedRoute
?
如果您想将其存储在变量中,您可以在 it 函数中使用 TestBed.get(ActivatedRoute)
获取它。您也可以更新值。
从 angular 的最新版本的 Karma v9.0.0 开始,TestBed.get
方法已弃用
如果您不使用 testBed
则使用这行代码:
在beforeEach
方法中,activatedRoute
mock应该定义如下:
activatedRoute = {queryParams: of({id: 1})};
然后在您的 it 方法中,将 activatedRoute 更新为:
activatedRoute.queryParams = of({id: 2})};
有一个带有存根的替代方案class。按照下面的方法。
声明存根 class
class ActivatedRouteStub {
private _params = new Subject<any>();
get params() {
return this._params.asObservable();
}
public push(value) {
this._params.next(value);
}
}
在你的 beforeEach 中为激活的路由提供者声明一个别名
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [YourComponentComponent],
providers: [
{
provide: ActivatedRoute,
useClass: ActivatedRouteStub
}
]
})
.compileComponents();
}));
而且您可以在任何需要的地方使用它。下面是“it”测试中的示例。
it('should show example, how to set parameters', () => {
let spy = spyOn(router, 'navigate');
// here we pass the any parameter for return and type the route variable with the stub class
let route: ActivatedRouteStub = TestBed.inject<any>(ActivatedRoute);
// you can push the parameters like you desire.
route.push({id: 0})
expect(spy).toHaveBeenCalledWith(['not-found'])
});
归功于 Suresh 的正确答案,并从 Angular 9 开始稍微更新它 TestBed.get
已弃用。现在推荐的方法是
let activatedRoute: ActivatedRoute;
...
activatedRoute = TestBed.inject(ActivatedRoute);
activatedRoute.snapshot.params = { foo: 'bar' };
组件:
@Component({
selector: 'app-test',
templateUrl: './test.component.html'
})
export class TestComponent implements OnInit {
useCase: string;
constructor(
private route: ActivatedRoute,
) {}
ngOnInit() {
this.route.queryParams.subscribe(p => {
if (p) {
this.useCase = p.u;
}
});
}
}
测试规格
describe('TestComponent', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
AppModule
],
providers: [
{ provide: ActivatedRoute, useValue: ??? }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
expect(component.useCase).toBeFalsy();
});
it('should set useCase variable with query string value', () => {
fixture.detectChanges();
// Set different route.queryParams here...
expect(component.useCase).toBe('success');
});
});
使用Angular6、Karma和Jasmine进行单元测试。
我知道我们可以将 ActivatedRoute
设置为将在整个测试过程中使用的对象,例如:
providers: [
{ provide: ActivatedRoute, useValue: {
queryParams: Observable.of({id: 123})
} }
]
但这将为所有测试用例设置值。有没有办法在每个不同的测试用例中动态更改 ActivatedRoute
?
如果您想将其存储在变量中,您可以在 it 函数中使用 TestBed.get(ActivatedRoute)
获取它。您也可以更新值。
从 angular 的最新版本的 Karma v9.0.0 开始,TestBed.get
方法已弃用
如果您不使用 testBed
则使用这行代码:
在beforeEach
方法中,activatedRoute
mock应该定义如下:
activatedRoute = {queryParams: of({id: 1})};
然后在您的 it 方法中,将 activatedRoute 更新为:
activatedRoute.queryParams = of({id: 2})};
有一个带有存根的替代方案class。按照下面的方法。
声明存根 class
class ActivatedRouteStub {
private _params = new Subject<any>();
get params() {
return this._params.asObservable();
}
public push(value) {
this._params.next(value);
}
}
在你的 beforeEach 中为激活的路由提供者声明一个别名
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [YourComponentComponent],
providers: [
{
provide: ActivatedRoute,
useClass: ActivatedRouteStub
}
]
})
.compileComponents();
}));
而且您可以在任何需要的地方使用它。下面是“it”测试中的示例。
it('should show example, how to set parameters', () => {
let spy = spyOn(router, 'navigate');
// here we pass the any parameter for return and type the route variable with the stub class
let route: ActivatedRouteStub = TestBed.inject<any>(ActivatedRoute);
// you can push the parameters like you desire.
route.push({id: 0})
expect(spy).toHaveBeenCalledWith(['not-found'])
});
归功于 Suresh 的正确答案,并从 Angular 9 开始稍微更新它 TestBed.get
已弃用。现在推荐的方法是
let activatedRoute: ActivatedRoute;
...
activatedRoute = TestBed.inject(ActivatedRoute);
activatedRoute.snapshot.params = { foo: 'bar' };