2017-06-16 251 views
0

我正在爲具有依賴項的服務創建一個簡單的單元測試。這是一個簡單的服務,我開始幫助我瞭解最佳流程和結構。使用Angular 2注入依賴項的單元測試服務

我創建的單元測試工作,但TypeScript引發錯誤。

Argument of type '{ order_id: string; user: string; }' is not assignable to parameter of type 'Expected<Observable<any>>'. 
Object literal may only specify known properties, and 'order_id' does not exist in type 'Expected<Observable<any>>'. 

該服務對注入的服務執行發送HTTP請求的方法sendBody。我明白應該返回一個Observable,但我會認爲模擬服務應該已經解決了這個TypeScript類型的錯誤。

僅在測試服務時是否有更好的方法來注入和模擬依賴項?

服務

export class ReturnOrderService { 

    constructor(private _ReturnOrderResource: ReturnOrderResource) { } 

    updateOrderStatus(orderId: string, user: string) { 
     let body = {}; 

     if (orderId !== undefined && user !== undefined) { 
      body["order_id"] = orderId; 
      body["user"] = user; 
     } 

     return this._ReturnOrderResource.sendBody(body); 
    } 

} 

規格

const MockReturnOrderResource = { 
sendBody: function(body) { 
    return body; 
    } 
} 

describe('ReturnsComponent',() => { 

    beforeEach(() => { 
    TestBed.configureTestingModule({ providers: [ 
     ReturnOrderService, 
     { provide: ReturnOrderResource, useValue: MockReturnOrderResource } 
     ] }); 
    }); 

    it('#updateOrderStatus should create an object literal from arguments', 
    async(inject([ReturnOrderService], (service: ReturnOrderService) => { 
     expect(service.updateOrderStatus("10006886","Mr Bungle")).toEqual({ order_id: '10006886', user: 'Mr Bungle' }); 
    }))); 

}); 
+0

是什麼'_ReturnOrderResource.sendBody'返回?你可以添加該代碼嗎? – sabithpocker

+0

@sabithpocker它通過幾個不同的服務,但本質上只是使用Angular 2 Http類和Request方法發出POST請求:https://angular.io/api/http/Http#request。所以一個Observable預計將返回 – bmd

回答

0

我已經通過一個解決方案使用了不同的方法工作了這一點。雖然它可能無法解決我遇到的類型錯誤,但它允許我監視注入的服務,這正是我之前的服務。

注入服務後,我使用TestBed.get()獲取服務並將其分配給一個變量。

然後,我可以偵測注入的服務,並針對調用該方法的參數進行測試。

下面更新的規格。

const MockReturnOrderResource = { 
    sendBody: function(body) { 
    return body; 
    } 
} 

describe('ReturnsComponent',() => { 
    let _ReturnOrderResource; 

    beforeEach(() => { 
    TestBed.configureTestingModule({ providers: [ 
     ReturnOrderService, 
     { provide: ReturnOrderResource, useValue: MockReturnOrderResource } 
     ] }); 
    _ReturnOrderResource = TestBed.get(ReturnOrderResource); 
    }); 

    it('#updateOrderStatus should pass an object literal as an argument', 
    async(inject([ReturnOrderService], (service: ReturnOrderService) => { 
    spyOn(service, "updateOrderStatus").and.callThrough(); 
    spyOn(_ReturnOrderResource, "sendBody").and.callThrough(); 
    service.updateOrderStatus("10006886","Mr Bungle"); 
    expect(_ReturnOrderResource.sendBody).toHaveBeenCalledWith({ order_id: '10006886', user: 'Mr Bungle' }) 
    }))); 

}); 

爲了解決此解決方案進一步閱讀:https://angular.io/guide/testing#testbedget

0

如果必須返回一個可觀察,然後返回一個可觀察!

試試這個:

const MockReturnOrderResource = { 
    sendBody: (any: any) => Observable.of(any); 
} 
+0

謝謝,trichetriche。我確實嘗試過類似的(現在是上面的),但是仍然得到相同的類型錯誤。儘管測試本身在每種情況下都是奇數。 – bmd

+0

你錯誤的地方是,你期望一個類型爲'Expected >'的參數,但你提供了一個自定義對象。我建議你發現這個錯誤,你應該能夠抑制這個錯誤。 – trichetriche

+0

再次感謝您的幫助。我能夠找到一個解決方案使用不同的方法來獲得注入的服務,並創建一個測試。我在這個線程中包含了答案 – bmd