Angular2 - 在测试中模拟 RouteParams
Angular2 - mocking RouteParams in test
我在为 Angular2 组件的测试中注入 RouteParams 依赖项的模拟时遇到了一些问题。我的总体想法是我可能缺少一些提供者。
测试失败:
Cannot resolve all parameters for 'RouteParams'(?). Make sure that all the parameters are decorated with Inject
or have valid type annotations and that 'RouteParams' is decorated with Injectable.
有人知道问题出在哪里吗?
import {
it,
inject,
injectAsync,
describe,
beforeEach,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
import {Component, provide} from 'angular2/core';
import {BaseRequestOptions, Http} from 'angular2/http';
import {MockBackend} from 'angular2/http/testing';
import {RouteParams, ROUTER_PROVIDERS, ROUTER_PRIMARY_COMPONENT} from 'angular2/router';
// Load the implementations that should be tested
import {Home} from './home';
import {Title} from './providers/title';
describe('Home', () => {
// provide our implementations or mocks to the dependency injector
beforeEachProviders(() => [
Title,
Home,
provide(RouteParams, { useValue: new RouteParams({ id: '1' }) }),
BaseRequestOptions,
MockBackend,
provide(Http, {
useFactory: function(backend, defaultOptions) {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
}),
provide(RouteParams, {
useFactory: function() {
return new RouteParams({ 'id':'1' });
}
})
]);
it('should have a title', inject([ Home ], (home) => {
expect(home.title.value).toEqual('Angular 2');
}));
it('should have a http', inject([ Home ], (home) => {
expect(!!home.http).toEqual(true);
}));
it('should log ngOnInit', inject([ Home ], (home) => {
spyOn(console, 'log');
spyOn(console, 'info');
expect(console.log).not.toHaveBeenCalled();
expect(console.info).not.toHaveBeenCalled();
home.ngOnInit();
expect(console.log).toHaveBeenCalled();
expect(console.info).toHaveBeenCalledWith('1');
}));
});
我自己设法解决了这个问题,您使用
provide(RouteParams, { useValue: new RouteParams({ id: '1' }) })
模拟了 RouteProvider
import {
it,
inject,
injectAsync,
describe,
beforeEach,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
import {Component, provide} from 'angular2/core';
import {BaseRequestOptions, Http} from 'angular2/http';
import {MockBackend} from 'angular2/http/testing';
import {RouteParams, ROUTER_PROVIDERS, ROUTER_PRIMARY_COMPONENT} from 'angular2/router';
// Load the implementations that should be tested
import {Home} from './home';
import {Title} from './providers/title';
describe('Home', () => {
// provide our implementations or mocks to the dependency injector
beforeEachProviders(() => [
Title,
Home,
provide(RouteParams, { useValue: new RouteParams({ id: '1' }) }),
BaseRequestOptions,
MockBackend,
provide(Http, {
useFactory: function(backend, defaultOptions) {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
})
]);
it('should have a title', inject([ Home ], (home) => {
expect(home.title.value).toEqual('Angular 2');
}));
it('should have a http', inject([ Home ], (home) => {
expect(!!home.http).toEqual(true);
}));
it('should log ngOnInit', inject([ Home ], (home) => {
spyOn(console, 'log');
spyOn(console, 'info');
expect(console.log).not.toHaveBeenCalled();
expect(console.info).not.toHaveBeenCalled();
home.ngOnInit();
expect(console.log).toHaveBeenCalled();
expect(console.info).toHaveBeenCalledWith('1');
}));
});
对于即使在使用 Angular4
的情况下登陆这里的人
我只是继续创建了一个模拟。我想诀窍是模拟你需要的 ActivatedRoute
部分。对我来说,它做到了:
import {ActivatedRoute, ParamMap} from '@angular/router';
/**
* Mocking the ActivatedRoute which is injected in the Component on creation.
* This allows for easier testing as values can be set as needed.
*/
class MockActivatedRoute {
paramMap = Observable.of(new Params());
}
/**
* Bare bones implementation of ParamMap used in mock. Further tests can expand
* on this implementation as needed.
*/
class Params implements ParamMap {
keys: string[];
private routes: {[key: string]: string|null} = {
subject: 'foo',
time: 'd-123-1',
device: 'all',
location: 'c-123'
};
constructor() {
this.keys = Object.keys(this.routes);
}
has(name: string): boolean {
throw new Error('Method not implemented.');
}
get(name: string): string|null {
return this.routes[name];
}
getAll(name: string): string[] {
throw new Error('Method not implemented.');
}
}
然后确保在您的测试模块中,您通过真实 ActivatedRoute
:
提供模拟服务
providers: [
{
provide: ActivatedRoute,
useValue: new MockActivatedRoute(),
}
]
为了完成,我在我正在测试的组件中使用它的方式:
ngOnInit() {
this.route.paramMap
.map((params: ParamMap) => params.get('subject') as string)
.subscribe((subject: string) => this.subject = subject);
}
我在为 Angular2 组件的测试中注入 RouteParams 依赖项的模拟时遇到了一些问题。我的总体想法是我可能缺少一些提供者。
测试失败:
Cannot resolve all parameters for 'RouteParams'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'RouteParams' is decorated with Injectable.
有人知道问题出在哪里吗?
import {
it,
inject,
injectAsync,
describe,
beforeEach,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
import {Component, provide} from 'angular2/core';
import {BaseRequestOptions, Http} from 'angular2/http';
import {MockBackend} from 'angular2/http/testing';
import {RouteParams, ROUTER_PROVIDERS, ROUTER_PRIMARY_COMPONENT} from 'angular2/router';
// Load the implementations that should be tested
import {Home} from './home';
import {Title} from './providers/title';
describe('Home', () => {
// provide our implementations or mocks to the dependency injector
beforeEachProviders(() => [
Title,
Home,
provide(RouteParams, { useValue: new RouteParams({ id: '1' }) }),
BaseRequestOptions,
MockBackend,
provide(Http, {
useFactory: function(backend, defaultOptions) {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
}),
provide(RouteParams, {
useFactory: function() {
return new RouteParams({ 'id':'1' });
}
})
]);
it('should have a title', inject([ Home ], (home) => {
expect(home.title.value).toEqual('Angular 2');
}));
it('should have a http', inject([ Home ], (home) => {
expect(!!home.http).toEqual(true);
}));
it('should log ngOnInit', inject([ Home ], (home) => {
spyOn(console, 'log');
spyOn(console, 'info');
expect(console.log).not.toHaveBeenCalled();
expect(console.info).not.toHaveBeenCalled();
home.ngOnInit();
expect(console.log).toHaveBeenCalled();
expect(console.info).toHaveBeenCalledWith('1');
}));
});
我自己设法解决了这个问题,您使用
provide(RouteParams, { useValue: new RouteParams({ id: '1' }) })模拟了 RouteProvider
import {
it,
inject,
injectAsync,
describe,
beforeEach,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
import {Component, provide} from 'angular2/core';
import {BaseRequestOptions, Http} from 'angular2/http';
import {MockBackend} from 'angular2/http/testing';
import {RouteParams, ROUTER_PROVIDERS, ROUTER_PRIMARY_COMPONENT} from 'angular2/router';
// Load the implementations that should be tested
import {Home} from './home';
import {Title} from './providers/title';
describe('Home', () => {
// provide our implementations or mocks to the dependency injector
beforeEachProviders(() => [
Title,
Home,
provide(RouteParams, { useValue: new RouteParams({ id: '1' }) }),
BaseRequestOptions,
MockBackend,
provide(Http, {
useFactory: function(backend, defaultOptions) {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
})
]);
it('should have a title', inject([ Home ], (home) => {
expect(home.title.value).toEqual('Angular 2');
}));
it('should have a http', inject([ Home ], (home) => {
expect(!!home.http).toEqual(true);
}));
it('should log ngOnInit', inject([ Home ], (home) => {
spyOn(console, 'log');
spyOn(console, 'info');
expect(console.log).not.toHaveBeenCalled();
expect(console.info).not.toHaveBeenCalled();
home.ngOnInit();
expect(console.log).toHaveBeenCalled();
expect(console.info).toHaveBeenCalledWith('1');
}));
});
对于即使在使用 Angular4
的情况下登陆这里的人我只是继续创建了一个模拟。我想诀窍是模拟你需要的 ActivatedRoute
部分。对我来说,它做到了:
import {ActivatedRoute, ParamMap} from '@angular/router';
/**
* Mocking the ActivatedRoute which is injected in the Component on creation.
* This allows for easier testing as values can be set as needed.
*/
class MockActivatedRoute {
paramMap = Observable.of(new Params());
}
/**
* Bare bones implementation of ParamMap used in mock. Further tests can expand
* on this implementation as needed.
*/
class Params implements ParamMap {
keys: string[];
private routes: {[key: string]: string|null} = {
subject: 'foo',
time: 'd-123-1',
device: 'all',
location: 'c-123'
};
constructor() {
this.keys = Object.keys(this.routes);
}
has(name: string): boolean {
throw new Error('Method not implemented.');
}
get(name: string): string|null {
return this.routes[name];
}
getAll(name: string): string[] {
throw new Error('Method not implemented.');
}
}
然后确保在您的测试模块中,您通过真实 ActivatedRoute
:
providers: [
{
provide: ActivatedRoute,
useValue: new MockActivatedRoute(),
}
]
为了完成,我在我正在测试的组件中使用它的方式:
ngOnInit() {
this.route.paramMap
.map((params: ParamMap) => params.get('subject') as string)
.subscribe((subject: string) => this.subject = subject);
}