我如何在茉莉花的控制器中模拟这个$ resource服务?

时间:2014-11-21 20:04:35

标签: angularjs jasmine

我是新手测试并试图在AngularJS中使用我的控制器进行这个Jasmine测试设置。我有一个可以重用的服务我想模拟,但我不断收到错误(具体来说,服务总是失败,我得到“无法连接到API服务”)。以下是我的尝试。

我的控制器:

angular
  .module('myApp')
  .controller('myController', myController);

function myController($scope, apiService) {
  apiService.url = "/api/getAccount";
  apiService.call().get({ accountNumber: 123 }).$promise.then(function (data) {
      $scope.account = data;
  }, function () {
    throw new Error("Cannot connect to the API service");
  });

服务:

angular
    .module('myApp')
    .factory('apiService', apiService);

function apiService($resource) {
    return {
        url: '/api/..',
        call: function () {
            return $resource(this.url);
        }
    }
};

我的茉莉花测试:

describe('myController', function () {
     var $q,
     $rootScope,
     $scope,
     mockAccountListResponse = { Account: [{ //stuff }] },
     mockApiService,
     deferred;

  beforeEach(module('myApp'));

  beforeEach(inject(function (_$q_, _$rootScope_) {
    $q = _$q_;
    $rootScope = _$rootScope_;
  }));

  beforeEach(inject(function ($controller) {
    $scope = $rootScope.$new();

  mockApiService = {
     call: function () {
       return {
         get: function () {
           deferred = $q.defer();
           deferred.reject("Error Connecting to API Service");
           return { $promise: deferred.promise };
         }
       }
     }
   }

    spyOn(mockApiService, 'call').and.callThrough();

    $controller('dashboardController', {
      '$scope': $scope,
      'apiService': mockApiService,
    });
  }));

  describe('Upon calling the ApiService', function () {

    beforeEach(function () {
      deferred.resolve(mockAccountResponse);
      $rootScope.$apply();
    });

    it('should get the account successfully', function () {
      expect(mockApiService.call).toHaveBeenCalled();
    });
  });
});

1 个答案:

答案 0 :(得分:1)

嗯,实际上在设置模拟时会导致问题发生。你看到你说的那条线:

deferred.reject("Error Connecting to API Service");

您基本上是说,无论何时调用此模拟服务,都会返回被拒绝的承诺,以便使用它的任何其他人都将获得此拒绝的值,并且不会输入.then。现在,您只是检查是否已调用.get,但我认为在您的断言被考虑之前,它会从承诺中抛出未处理的异常。你为什么不解决呢? deferred.resolve("Here's a good test value");

由于您不熟悉测试,如果我没有提到有一个很酷的模拟库,它会自动模仿任何使用底层$ httpBackend服务的东西,而且包括angular $ resource服务因为它依赖于$ httpBackend。

如果您设置了包含所述库的测试html页面,那么您的所有网络请求都将被模拟,您将可以访问他们尝试通过网络发送的值。

这是模拟库:https://docs.angularjs.org/api/ngMock。我建议试一试!