使用实际和模拟依赖项测试Angular服务

时间:2015-12-09 15:26:18

标签: angularjs unit-testing

我有一项服务,我需要使用2个真正的注入对象和1个模拟。 我已阅读(并在另一个类中使用)这篇文章Injecting a mock into an AngularJS service如何模拟服务依赖项,但我无法弄清楚如何在单元测试中创建我的服务 appConfigsessionStorage嘲笑,并使用真实$resource

这是我的服务

.factory('accountService',
    [
        'appConfig',
        'sessionStorage',
        '$resource',
        function accountService_init (appConfig, sessionStorage, $resource){

            // some account methods are done on a web endpoint
            var webauthendpoint = appConfig.locations.authEndPoint + ':method';

            // Others are done on the API endpoint
            var Account = $resource(appConfig.locations.api.account, {
                method: '@method'
            });

            //removed code

            return Account;
        }
    ]
);

所以我看到了所有依赖项都被模拟的代码(在beforeEach中使用$provide.value,之后可以在expect中注入对象,如下所示:

it('should return value from mock dependency', inject(function (myService) {
      expect(myService.useDependency()).toBe('mockReturnValue');
  }));

我已经看到(并使用过)依赖于questionsPersistenceService的服务userPrefilledPersistService的示例:

beforeEach(inject(function (_questionsPersistenceService_, _userPrefilledPersistService_) {
        questionsPersistenceService = _questionsPersistenceService_;
        userPrefilledPersistService = _userPrefilledPersistService_;
    }));

但如何结合?

编辑,因为我的问题已被确定为另一个问题的可能副本。

@Estus:可能重复?那篇文章是关于在指令中嘲笑服务。在我的帖子中,我已经说过我知道该怎么做,但我的问题是如何在同一个测试中结合注入实时依赖项和模拟依赖项

1 个答案:

答案 0 :(得分:2)

你可以把它结合起来 但是你也可以注入所有的依赖关系:

var dep1, dep2, dep3;

beforeEach(inject(function(_dependency1_, _dependecy2_, _dependecy3_){
   dep1 = _dependency1_;
   spyOn(dep1, 'methodYouUseLikeReal').and.callThrough();

   dep2 = _dependecy2_;
   spyOn(dep2, 'otherMethodYouUseTheOriginalCode').and.callThrough();

   dep3 = _dependecy3_;
   spyOn(dep3, 'methodYouLikeToMock').and.respond(
       function() {
            return 'someMockValueOrFunctionality';
       }
   );
}));

然后在你的测试用例上:

it('returns true expected value for dep1 and dep2 and someMockValueOrFunctionality for dep3', function (){
    var result1 = dep1.methodYouUseLikeReal();
    expect(dep1.methodYouUseLikeReal).toHaveBeenCalled();
    expect(result1).toBe('real expected result');

    var result2 = dep2.otherMethodYouUseTheOriginalCode(param);
    expect(dep2.otherMethodYouUseTheOriginalCode).toHaveBeenCalledWith(param);
    expect(dep2.otherMethodYouUseTheOriginalCode).toBe('real result');

    var result3 = dep3.methodYouLikeToMock();
    expect(dep3.methodYouLikeToMock).toHaveBeenCalled();
    expect(result3).toBe('someMockValueOrFunctionality');
});

我希望这会对你有所帮助。