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

当单元测试一个 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允许控制器使用这种方法,但是我没有看到工厂使用这种方法。

60795 次浏览

据我所知,有两种方法可以达到这种效果:

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

@ bentzai 的注释实际上对于测试服务非常有帮助; 为了完整起见,我将添加一个示例。

这里有一个 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()允许您引入依赖项,就像您在正常的角度应用程序中所期望的那样——因此,您可以构建需求来支持依赖于它们的测试。