【问题标题】:Unit test service with injected dependency using Angular 2使用 Angular 2 注入依赖的单元测试服务
【发布时间】:2017-11-19 01:43:18
【问题描述】:

我正在为具有依赖关系的服务创建一个简单的单元测试。这是一项简单的服务,我开始着手帮助我了解最佳流程和结构。

我创建的单元测试有效,但 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>>'.

服务在注入的服务上执行方法 sendBody ,该方法发出 HTTP 发布请求。我知道应该在这里返回一个 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' });
  })));

});

【问题讨论】:

  • _ReturnOrderResource.sendBody 返回什么?您也可以添加该代码吗?
  • @sabithpocker 它通过几个不同的服务传递,但本质上只是使用 Angular 2 Http 类和 Request 方法发出 POST 请求:angular.io/api/http/Http#request。所以预期会返回一个 Observable

标签: angular unit-testing jasmine karma-runner


【解决方案1】:

如果它必须返回一个 Observable,则返回一个 Observable !

试试这个:

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

【讨论】:

  • 谢谢,毛毛虫。我确实尝试了类似的东西(现在是上面的),但继续得到相同的类型错误。尽管测试本身在每种情况下都通过了,但这很奇怪。
  • 您的错误是在某处,您期望Expected&lt;Observable&lt;any&gt;&gt; 类型的参数,但您提供了一个自定义对象。我建议你找到这个错误,你应该能够抑制这个错误。
  • 再次感谢您的帮助。我能够使用不同的方法找到一个解决方案来获取注入的服务并针对它创建一个测试。我已将答案包含在此线程中
【解决方案2】:

我已经使用不同的方法解决了这个问题。虽然它可能无法解决我遇到的类型错误,但它允许我窥探注入的服务,这正是我所追求的。

注入服务后,我使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-23
    • 2017-11-30
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多