如何在测试中模拟NavParams?

Ka *_*Mok 10 unit-testing ionic2 angular2-testing angular

这可能只是一个Ionic 2问题,因为我没有在Angular 2文档中看到NavParams,但是有些概念可能会翻译,所以我标记了两者.

鉴于我navparams.get('somekey')为了侦听传入的参数而调用,在测试中模拟NavParams是很棘手的.

例如,以下是我目前的工作方式:

export class NavParamsMock {
  public get(key): any {
    return String(key) + 'Output';
  }
}
Run Code Online (Sandbox Code Playgroud)

这适用于真正的基本测试,但如果我有一个组件,我必须测试它gets是一种特定类型Object,例如a User.

然后,我可以做类似的事情

export class NavParamsMock {
  public get(key): any {
    if (key === 'user') {
       return new User({'name':'Bob'})
    }
    return String(key) + 'Output';
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您想get(user)在另一个测试中使用,或者甚至是另一个组件的规范,则这不起作用.假设您在两个不同的组件中使用NavParams,并且当您这样做时它们都期望不同的结果get(user),模拟变得越来越棘手.

有没有人找到这种情况的解决方案?

raj*_*raj 12

您可以通过实施自己的setter方法获得您选择的价值.

export class NavParamsMock {
  static returnParam = null;
  public get(key): any {
    if (NavParamsMock.returnParam) {
       return NavParamsMock.returnParam
    }
    return 'default';
  }
  static setParams(value){
    NavParamsMock.returnParam = value;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在每个测试中,您可以访问该服务并设置您自己的params对象.

beforeEach(() => {
  NavParamsMock.setParams(ownParams); //set your own params here
  TestBed.configureTestingModule({
    providers: [
      {provide: NavParams, useClass: NavParamsMock},
    ]
  });
})
Run Code Online (Sandbox Code Playgroud)


Mal*_*ina 7

而不是嘲笑类,最简单的方法是创建NavParams类的实例,然后使用它.NavParams使该data属性可公开分配,因此可以根据需要在每个测试中进行修改.

以下示例假设您的页面看起来像这样:

@IonicPage()
@Component({...})
export class YourPage {
  private data: string;

  constructor(navParams: NavParams) {
    this.data = navParams.get('data');
  }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,你叫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');
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

如果您的页面navParams.get('key')在任何地方调用而不是分配给私有成员,那么只需navParams.data在每次测试中重新分配属性就足够了(不需要generateFixture()每次都调用).