单元测试具有依赖关系的AngularJS工厂

Roy*_*ove 76 jasmine angularjs karma-runner

当单元测试Angular工厂(使用Karma + Jasmine)时,如何将存根依赖注入到被测工厂中?

这是我的工厂:

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

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

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();

    }
  ]);
})
Run Code Online (Sandbox Code Playgroud)

NB我知道这$controller允许控制器,但我没有看到工厂的等价物.

Noa*_*tas 91

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

  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();
  }));
});
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答+1.为完整性添加代码#2的代码示例会很不错. (10认同)
  • 我想将myFactory注入所有测试中.可以在beforeEach中完成吗?我试过但它不起作用...... (7认同)
  • @BennettMcElwee是的,你可以.像这样:`var theFactory; beforeEach(inject(function(myFactory){theFactory = myFactory;})));`然后在测试中使用`theFactory`. (2认同)

AJ.*_*AJ. 12

@bentsai的评论实际上对测试服务很有帮助; 为了完整性我正在添加一个例子.

这是一个测试,jasmine大概是你正在寻找什么.注意:这要求您angular-mocks包含(这是提供类似module和的功能inject).

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))
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

这是模块和相关工厂定义可能如下所示的存根:

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

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

  • 您错过了在测试中向MyFactory注入存根依赖项的部分. (2认同)