2017-06-16 259 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