80

在对 Angular 工厂(使用 Karma + Jasmine)进行单元测试时,如何将存根依赖项注入被测工厂?

这是我的工厂:

mod = angular.module('myFactoryMod', []);

mod.factory('myFactory', [
  '$log', 'oneOfMyOtherServices', function($log, svc) {
    return makeSomethingThatDoesSomethingWithTheseDependencies($log, svc);
  }
]);

oneOfMyOtherServices实例化我的工厂时需要。

这是我的测试:

it('can get an instance of my factory', function() {
  var oneOfMyOtherServicesStub;

  angular.mock.module('myFactoryMod');

  oneOfMyOtherServicesStub = {
    someVariable: 1
  };

  //****How do I get my stub in my target? ****

  angular.mock.inject(['myFactory', function(target) {

      expect(target).toBeDefined();

    }
  ]);
})

注意我知道这$controller允许控制器使用,但我没有看到工厂的等效项。

4

2 回答 2

94

我知道有两种方法可以完成这样的事情:

  1. 使用$provide和一个匿名模块来注入模拟。
  2. 注入您想要模拟的服务,并使用 jasmine 的间谍功能来提供模拟值。

第二个选项只有在您确切知道您的测试代码将在注入的服务上调用哪些方法并且您可以轻松地模拟它们时才有效。由于您似乎正在访问服务(而不是方法)上的数据属性,因此追求第一个选项可能是最好的。

使用$provide大致如下所示:

describe('myFactory', function () {
  // Load your module.
  beforeEach(module('myFactoryMod'));

  // Setup the mock service in an anonymous module.
  beforeEach(module(function ($provide) {
    $provide.value('oneOfMyOtherServicesStub', {
        someVariable: 1
    });
  }));

  it('can get an instance of my factory', inject(function(myFactory) {
    expect(myFactory).toBeDefined();
  }));
});
于 2013-05-15T14:30:18.477 回答
12

@bentsai 的评论实际上对测试服务很有帮助;为了完整起见,我添加了一个示例。

这是一个测试,jasmine它大约可以满足您的需求。注意:这要求您已经angular-mocks包含(这是提供和 之类的功能moduleinject

describe('app: myApp', function() {
  beforeEach(module('myApp'));
  var $controller;
  beforeEach(inject(function(_$controller_) {
    $controller = _$controller_;
  }));
  // Factory of interest is called MyFactory
  describe('factory: MyFactory', function() {
    var factory = null;
    beforeEach(inject(function(MyFactory) {
      factory = MyFactory;
    }))
    it('Should define methods', function() {
      expect(factory.beAwesome).toBeDefined()
      expect(factory.beAwesome).toEqual(jasmine.any(Function))
    });
  });
});

这是模块和相关工厂定义的存根:

var app = angular.module('myApp', []);
app.factory('MyFactory', function() {
  var factory = {};
  factory.beAwesome = function() {
    return 'Awesome!';
  }
  return factory;
});

在这种情况下,很明显,使用inject()允许您引入依赖项,就像您在正常的 Angular 应用程序中所期望的那样 - 因此您可以构建需求以支持测试依赖它们的事物。

于 2014-11-26T07:53:45.640 回答