문제

We have an analytics service which is dependency injected to most of our controllers to help us track actions users make.

Rather than going through setting up the mock version of this service every time a test suite is created it's preferred to take the ngMock approach and abstract the mocking. What's the best approach?

도움이 되었습니까?

해결책

EDIT

Looks like you can just override the service by loading a module which replaces it.

http://plnkr.co/edit/mHI19j6FDtV8UElRWvUs?p=preview


http://plnkr.co/edit/lZg8eQdoQRNtqedcr2UU?p=preview

One thing you could do, if I understand your issue correctly, is to not have your modules with your controller depend on that tracking service, and put that dependency in at the app level. Then, in your tests, just load the module containing the mocked version explicitly.

So like:

var core = angular.module('core', []);
var analytics = angular.module('analytics', []);
var app = angular.module('plunker', ['analytics', 'core']);
var mockAnalytics = angular.module('mockAnalytics', []);

core.controller('MainCtrl', function($scope, tracker) {
  $scope.track = tracker.track();
});

analytics.factory('tracker', function () {
  var service = {};

  service.track = function () {
    return "I'm real";
  }

  return service;
});

mockAnalytics.factory('tracker', function () {
  var service = {};

  service.track = function () {
    return "I'm a mock";
  }

  return service;
});

Tests:

describe('Testing a controller', function() {
  var $scope = null;
  var ctrl = null;

  beforeEach(module('core'));
  beforeEach(module('mockAnalytics'));

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

    ctrl = $controller('MainCtrl', {
      $scope: $scope
    });
  }));

  it('should have its $scope.track == "I\'m a mock"', function() {
    expect($scope.track).toEqual("I'm a mock");
  });
});
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top