如何监视调用另一个服务的服务功能 returns 一个承诺 - 打字稿

How to spy on a service function that calls another service which returns a promise - typescript

家长服务:

module proj.Stuff {
  export class ParentService {
    //...properties, constructor, etc

    public refreshStuff(id: number) {
      this.childService
        .getStuff(id)
        .then((response) => this.stuff = response);
      }
   }
}

儿童服务:

module proj.Stuff {
  export class ChildService{
    //... properties, constructor, etc

    public getStuff(id: number) {

      var request: IPromise<any> = this.$http.get(
      ChildService.apiUrlBase + "getStuff/" + id
      );

      return request
       .then(response => {
         return response.data.value;
      }, response => {
        this.$log.error("unable to get...");
      });
    }
  }
}

父服务测试:

describe("ParentService", () => {

  // (property declarations omitted for brevity)

  beforeEach(angular.mock.module(["$provide", ($provide) => {

    var obj = {
      getStuff: (id: number) => {
        functionCalled = true;
        return {
          then: (callback) => {
            return callback(["result"]);
          }
        };
      }
    };

    $provide.value("ChildService", obj);
  }]));

  beforeEach(mock.inject((_$http_, _$log_, _$q_, _$httpBackend_, _$rootScope_, _ChildService_) => {
    cService = _ChildService_;
    pService = new ParentService(cbService);
  }));

  it("can be created", () => {
    expect(pService).toBeDefined();
    expect(pService).not.toBeNull();
  });

  it("can refresh stuff", () => {
    pService.refreshStuff(1);
    expect(pService.stuff).toEqual(["result"]);
    expect(functionCalled).toBeTruthy();

    // ***** what I want to do: *****
    // expect(cService.getStuff).toHaveBeenCalled();
  });
});

我想知道如何监视 cService.getStuff 而不是使用 'functionCalled' 布尔值?

当我试图监视它时,它抱怨说 .then 没有定义——例如在第一个 beforeEach 中,如果我尝试 spyOn(obj, "getStuff") 它不喜欢它。

测试按原样通过,但宁愿使用 spyOn 而不是使用布尔值。

then 方法模拟很少被证明是合理的,Angular DI 允许使用未模拟的承诺并专注于单元测试。

  beforeEach(angular.mock.module(["$provide", ($provide) => {
    // allows to inject $q, while $provide.value doesn't
    $provide.factory("ChildService", ($q) => ({
      // fresh promise on every call
      getStuff: jasmine.createSpy('getStuff').and.callFake(() => $q.when('result'))
    }));
  }]));

最适用于 Jasmine promise matchers,否则应涉及常规承诺规范:

var result;
...then((_result) => { result = _result; })
$rootScope.$digest();
expect(result)...