AngularJS 单元测试:模拟的承诺已解决但方法仍然是 returns 承诺?

AngularJS Unit Test: Mocked promise is resolved but method still returns a promise?

我正在测试 'ServiceOne',它在第二个服务 'ServiceTwo' 中使用名为 "get" 的方法。 'ServiceTwo' 中的 get() 方法进行 $http 调用,因此它 returns 一个承诺,直到 $http 调用被解析。我要测试的 'ServiceOne' 方法如下所示:

serviceOne.getNewId = function (oldId) {
    var url = "http://mock.com";

    return serviceTwo.get(url).then(function (returned) {
        if (returned.data !== undefined) {
            return returned.data[0].newId;
        } else {
            return oldId;
        }
    });
};

这是我在 ServiceOne 中对 getNewId() 的测试:

beforeEach(angular.mock.inject(function (_serviceOne_,_$q_, _$rootScope_, _serviceTwo_) {

    serviceOne = _serviceOne_;
    serviceTwo = _serviceTwo_;

    $rootScope = _$rootScope_;
    deferred = _$q_.defer();
}));

it('should return a newId', inject(function (serviceTwo) {        
    spyOn(serviceTwo, 'get').and.returnValue(deferred.promise);

    var returnedData = {data:[{newId: '95'}]};
    deferred.resolve(returnedData);

    var retVal = serviceOne.getNewId('322');       
    $rootScope.$apply();

    expect(retVal).toBe('95');  //fails
}));

retVal 作为承诺对象返回,而不是预期的字符串“95”。因此,如果我进入 promise 对象并查找值,我可以让我的测试通过:

expect(retVal.$$state.value).toBe('95');  //passes

返回的promise对象的状态为1,所以我知道它已经解决了。并且 promise 的值是正确的,设置为“95”,就好像我的 then() 函数中的逻辑已被执行一样。为什么我在 运行 Karma 时收到此错误消息?

Expected Promise({ $$state: Object({ status: 1, value: '95' }) }) to be '95'.

因此,对于 promise,它们没有 return 价值,它们 return 是一个 promise,因此您必须像这样重组您的测试:

it('should return a newId', inject(function (serviceTwo) {        
    spyOn(serviceTwo, 'get').and.returnValue(deferred.promise);

    var returnedData = {data:[{newId: '95'}]};
    var retVal;

    serviceOne.getNewId('322')
        .then(function(result){
            retVal = result;
        });

    deferred.resolve(returnedData);

    $rootScope.$apply();

    expect(retVal).toBe('95');  //should pass
}));