2017-01-02 165 views
9

這可能只是一個Ionic 2的問題,因爲我沒有在Angular 2文檔中看到NavParams,但是一些概念可能會翻譯,因此我將兩者都標記了。如何在測試中模擬NavParams?

鑑於我呼叫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,當你做get(user)時,他們都期望得到不同的結果,它變得越來越棘手。

有沒有人找到了解決方案?

回答

8

您可以通過實施自己的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; 
    } 
} 

然後在每個測試中,您可以訪問該服務並設置您自己的params對象。

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

我得到一個「屬性returnParams在類型'NavParamsMock'上不存在......沒關係,你在returnParams之後錯過了一個s。 –

+0

有一個錯字。 ''returnParam'' – raj

4

我修改了@ raj的答案,用我自己的這種技術的變化。 @ raj只允許你設置一個參數。 Mine允許使用多個參數進行關鍵值存儲。

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; 
    } 
} 
+0

Property' data' missing.This是如何完成的:https://stackoverflow.com/questions/44658048/mocking-out-navparams-in-ionic-gives-back-property-data- is-missing-in-type-type – nottinhill

+0

@nottinhill這是一些離子3變化?所以在上面的實現中,我需要'擴展NavParams'? –

+0

是的,你可以擴展,但我全部嘲笑,讓我完全控制。 – nottinhill

1

而不是嘲諷了類,最簡單的方法只需要創建NavParams類的實例,然後使用它。 NavParams使data屬性可公開分配,因此可以根據需要在每個測試中修改它。

下面的例子假定您的網頁看起來是這樣的:

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

    constructor(navParams: NavParams) { 
    this.data = navParams.get('data'); 
    } 
} 

即,你叫navParams.get()在頁面constructorionViewDidLoad()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())。

+0

如果我有20個規格需要不同的導航參數,這是行不通的。我想動態設置每個規範內的導航參數,以適應每個測試用例。 –

+0

'NavParams'上的'data'屬性是公共的,如果需要可以在每個測試中設置。假設您在頁面的構造函數中使用'NavParams'中的數據訪問成員,則需要重新創建頁面以測試使用的新數據。但是,如果您始終直接訪問「NavParams」中的數據而不分配給本地成員,則只需重新分配「NavParams」的數據屬性即可。我已經更新了我的答案以匹配。 – Malina

0

在這裏是具有多個PARAMS

示例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 
    } 

} 

添加到測試牀提供商以下

{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() 
    })