Как издеваться над NavParams в тестах?
Это может быть только вопрос Ionic 2, так как я не вижу NavParams в документах Angular 2, но некоторые концепции могут переводиться, поэтому я отметил оба.
Учитывая, что я звоню navparams.get('somekey')
чтобы прослушивать передаваемые параметры, сложно насмехаться над NavParams в тестах.
Например, вот как я сейчас это делаю:
export class NavParamsMock {
public get(key): any {
return String(key) + 'Output';
}
}
Это работает для действительно базовых тестов, но что, если у меня есть компонент, который я должен проверить, что это gets
определенный тип Object
например, User
,
Тогда я могу сделать что-то вроде
export class NavParamsMock {
public get(key): any {
if (key === 'user') {
return new User({'name':'Bob'})
}
return String(key) + 'Output';
}
}
Но это не работает, если вы хотите использовать get(user)
в другом тесте или даже в спецификации другого компонента. Допустим, вы используете NavParams в 2 разных компонентах, и они оба ожидают разного результата, когда вы делаете get(user)
, становится все сложнее издеваться.
Кто-нибудь нашел решение по этому сценарию?
4 ответа
Вы можете получить значение по вашему выбору, реализовав свой собственный метод установки.
export class NavParamsMock {
static returnParam = null;
public get(key): any {
if (NavParamsMock.returnParam) {
return NavParamsMock.returnParam
}
return 'default';
}
static setParams(value){
NavParamsMock.returnParam = value;
}
}
Затем в каждом тесте вы можете получить доступ к сервису и установить свой собственный объект params.
beforeEach(() => {
NavParamsMock.setParams(ownParams); //set your own params here
TestBed.configureTestingModule({
providers: [
{provide: NavParams, useClass: NavParamsMock},
]
});
})
Вместо того, чтобы издеваться над классом, проще всего создать экземпляр NavParams
класс, а затем использовать его. NavParams
делает data
свойство публично присваивается, поэтому его можно изменять в каждом тесте по мере необходимости.
В приведенном ниже примере предполагается, что ваша страница выглядит примерно так:
@IonicPage()
@Component({...})
export class YourPage {
private data: string;
constructor(navParams: NavParams) {
this.data = navParams.get('data');
}
}
То есть ты звонишь navParams.get()
на вашей странице constructor
, ionViewDidLoad()
, ngOnInit()
или аналогичная функция инициализатора. В этом случае, чтобы изменить NavParams
данные и убедитесь, что он используется правильно, вам нужно изменить введенный тест navParams.data
собственности, а затем восстановить свою страницу:
import {IonicModule, NavParams} from 'ionic-angular';
import {ComponentFixture, TestBed} from '@angular/core/testing';
describe('YourPage', () => {
let fixture: ComponentFixture<YourPage>;
let component: YourPage;
const data = {data: 'foo'};
const navParams = new NavParams(data);
function generateFixture() {
fixture = TestBed.createComponent(YourPage);
component = fixture.componentInstance;
fixture.detectChanges();
}
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [YourPage],
imports: [
IonicModule.forRoot(YourPage),
],
providers: [
{provide: NavParams, useValue: navParams},
]
});
generateFixture();
});
describe('NavParams', () => {
it('should use injected data', () => {
expect(component['data']).toEqual('foo');
});
it('should use new injected data', () => {
const newData = {data: 'bar'};
navParams.data = newData;
generateFixture();
expect(component['data']).toEqual('bar');
});
});
});
Если ваша страница звонит navParams.get('key')
везде вместо назначения частному члену, а затем просто переназначения navParams.data
свойство достаточно в каждом тесте (не нужно вызывать generateFixture()
каждый раз).
Я изменил ответ @raj своим собственным вариантом этой техники. @raj's позволяет вам установить только один параметр. Мой позволяет хранить ключевые значения с несколькими параметрами.
export class NavParamsMock {
static returnParams: any = {};
public get(key): any {
if (NavParamsMock.returnParams[key]) {
return NavParamsMock.returnParams[key];
}
return 'No Params of ' + key + ' was supplied. Use NavParamsMock.setParams('+ key + ',value) to set it.';
}
static setParams(key,value){
NavParamsMock.returnParams[key] = value;
}
}
Вот пример с несколькими параметрами
NavParamsMock
export class NavParamsMock {
static returnParams: any = {}
public get (key): any {
if (NavParamsMock.returnParams[key]) {
return NavParamsMock.returnParams[key]
}
}
static setParams (key, value): any {
NavParamsMock.returnParams[key] = value
}
}
Добавьте к провайдерам TestBed следующее
{provide: NavParams, useClass: NavParamsMock}
Модульный тест
it('i am a unit test', () => {
const navParams = fixture.debugElement.injector.get(NavParams)
navParams.get =
jasmine
.createSpy('get')
.and
.callFake((param) => {
const params = {
'param1': 'value',
'param2': 'value'
}
return params[param]
})
comp.ionViewDidLoad()
})