使用 $provide 在 Jasmine 测试中重用 angular 模拟
Reusing angular mocks in Jasmine tests using $provide
我希望重用我的模拟,而不是必须在每个将它们作为依赖项的单元测试中设置它们。但是我很难弄清楚如何正确地注入它们。
这是我对单元测试设置的尝试,当然失败了,因为 ConfigServiceMockProvider 不存在。
describe('LoginService tests', function () {
var LoginService;
beforeEach(module('mocks'));
beforeEach(module('services.loginService', function ($provide, _ConfigServiceMock_) {
$provide.value("ConfigService", _ConfigServiceMock_);
/* instead of having to type e.g. everywhere ConfigService is used
* $provide.value("ConfigService", { 'foobar': function(){} });
*/
});
beforeEach(inject(function (_LoginService_) {
LoginService = _LoginService_;
});
}
ConfigServiceMock
angular.module('mocks').service('ConfigServiceMock', function() {
this.init = function(){};
this.getValue = function(){};
}
我意识到我可能 ConfigServiceMock.js 创建一个全局 window 对象,因此不需要像这样加载它。但是我觉得应该有更好的方法。
尝试这样的事情:
describe('Using externally defined mock', function() {
var ConfigServiceMock;
beforeEach(module('mocks'));
beforeEach(module('services.configService', function($provide) {
$provide.factory('ConfigService', function() {return ConfigServiceMock;});
}));
beforeEach(module('services.loginService'));
beforeEach(inject(function (_ConfigServiceMock_) {
ConfigServiceMock = _ConfigServiceMock_;
}));
// Do not combine this call with the one above
beforeEach(inject(function (_LoginService_) {
LoginService = _LoginService_;
}));
it('should have been given the mock', function() {
expect(ConfigServiceMock).toBeDefined('The mock should have been defined');
expect(LoginService.injectedService).toBeDefined('Something should have been injected');
expect(LoginService.injectedService).toBe(ConfigServiceMock, 'The thing injected should be the mock');
});
});
根据 this answer,您必须先将所有呼叫置于 module
,然后再呼叫 inject
。
这引入了一些陷阱 22,因为您必须在规范中引用您的 ConfigServiceMock(通过 inject
),然后才能在 LoginService 上设置它(在 [=11 中完成) =]呼叫)
解决方法是将 angular 工厂函数设置为 ConfigService 依赖项。这将导致 angular 延迟加载服务,到那时您将收到对 ConfigServiceMock 的引用。
我希望重用我的模拟,而不是必须在每个将它们作为依赖项的单元测试中设置它们。但是我很难弄清楚如何正确地注入它们。
这是我对单元测试设置的尝试,当然失败了,因为 ConfigServiceMockProvider 不存在。
describe('LoginService tests', function () {
var LoginService;
beforeEach(module('mocks'));
beforeEach(module('services.loginService', function ($provide, _ConfigServiceMock_) {
$provide.value("ConfigService", _ConfigServiceMock_);
/* instead of having to type e.g. everywhere ConfigService is used
* $provide.value("ConfigService", { 'foobar': function(){} });
*/
});
beforeEach(inject(function (_LoginService_) {
LoginService = _LoginService_;
});
}
ConfigServiceMock
angular.module('mocks').service('ConfigServiceMock', function() {
this.init = function(){};
this.getValue = function(){};
}
我意识到我可能 ConfigServiceMock.js 创建一个全局 window 对象,因此不需要像这样加载它。但是我觉得应该有更好的方法。
尝试这样的事情:
describe('Using externally defined mock', function() {
var ConfigServiceMock;
beforeEach(module('mocks'));
beforeEach(module('services.configService', function($provide) {
$provide.factory('ConfigService', function() {return ConfigServiceMock;});
}));
beforeEach(module('services.loginService'));
beforeEach(inject(function (_ConfigServiceMock_) {
ConfigServiceMock = _ConfigServiceMock_;
}));
// Do not combine this call with the one above
beforeEach(inject(function (_LoginService_) {
LoginService = _LoginService_;
}));
it('should have been given the mock', function() {
expect(ConfigServiceMock).toBeDefined('The mock should have been defined');
expect(LoginService.injectedService).toBeDefined('Something should have been injected');
expect(LoginService.injectedService).toBe(ConfigServiceMock, 'The thing injected should be the mock');
});
});
根据 this answer,您必须先将所有呼叫置于 module
,然后再呼叫 inject
。
这引入了一些陷阱 22,因为您必须在规范中引用您的 ConfigServiceMock(通过 inject
),然后才能在 LoginService 上设置它(在 [=11 中完成) =]呼叫)
解决方法是将 angular 工厂函数设置为 ConfigService 依赖项。这将导致 angular 延迟加载服务,到那时您将收到对 ConfigServiceMock 的引用。