假设我的服务shop
取决于两个有状态服务schedule
和warehouse
。如何将schedule
和warehose
的不同版本注入shop
进行单元测试?
这是我的服务:
angular.module('myModule').service('shop', function(schedule, warehouse) {
return {
canSellSweets : function(numRequiredSweets){
return schedule.isShopOpen()
&& (warehouse.numAvailableSweets() > numRequiredSweets);
}
}
});
这是我的嘲笑:
var mockSchedule = {
isShopOpen : function() {return true}
}
var mockWarehouse = {
numAvailableSweets: function(){return 10};
}
以下是我的测试:
expect(shop.canSellSweets(5)).toBe(true);
expect(shop.canSellSweets(20)).toBe(false);
答案 0 :(得分:52)
beforeEach(function () {
module(function ($provide) {
$provide.value('schedule', mockSchedule);
});
});
模块是角度模拟模块提供的功能。如果传入字符串参数,则会加载具有相应名称的模块,并且所有提供程序,控制器,服务等都可用于规范。通常使用注入功能加载它们。如果传入回调函数,将使用Angular的$ injector服务调用它。然后,该服务查看传递给回调函数的参数,并尝试推断应将哪些依赖项传递给回调。
答案 1 :(得分:36)
改进Atilla的回答并直接回答KevSheedy的评论,在module('myApplicationModule')
的背景下,你会做到以下几点:
beforeEach(module('myApplicationModule', function ($provide) {
$provide.value('schedule', mockSchedule);
}));
答案 2 :(得分:7)
使用CoffeeScript我遇到了一些问题,所以我最后使用 null :
beforeEach ->
module ($provide) ->
$provide.value 'someService',
mockyStuff:
value : 'AWESOME'
null
答案 3 :(得分:6)
您可以在此处查看更多信息
https://docs.angularjs.org/guide/services#unit-testing
您想要使用$ offer服务。在你的情况下
$provide.value('schedule', mockSchedule);
答案 4 :(得分:1)
我最近发布了ngImprovedTesting模块,它可以让AngularJS中的模拟测试变得更容易。
在你的例子中,你只需要在你的Jasmine测试中替换......
beforeEach(module('myModule'));
...与......
beforeEach(ModuleBuilder.forModule('myModule').serviceWithMocks('shop').build());
有关ngImprovedTesting的更多信息,请查看其介绍性博客文章: http://blog.jdriven.com/2014/07/ng-improved-testing-mock-testing-for-angularjs-made-easy/
答案 5 :(得分:1)
将模拟器放在模块上更简单:
beforeEach(function () {
module('myApp');
module({
schedule: mockSchedule,
warehouse: mockWarehouse
}
});
});
您可以使用注射来参考这些模拟进行预测试操作:
var mockSchedule;
var mockWarehouse;
beforeEach(inject(function (_schedule_, _warehouse_) {
mockSchedule = _schedule_;
mockWarehouse = _warehouse_;
}));
答案 6 :(得分:1)
我希望我的回答不是没用,但你可以通过$provide.service
beforeEach(() => {
angular.mock.module(
'yourModule',
($provide) => {
$provide.service('yourService', function() {
return something;
});
}
);
});
答案 7 :(得分:1)
当你使用茉莉花时,还有另一种方法可以使用茉莉花的间谍(https://jasmine.github.io/2.0/introduction.html#section-Spies)模仿调用。
使用这些功能可以使用函数调用进行定位,并在需要时允许对原始对象进行调用。它避免了使用$ provide和mock实现来堵塞测试文件的顶部。
在你的测试之前我会有类似的东西:
var mySchedule, myWarehouse;
beforeEach(inject(function(schedule, warehouse) {
mySchedule = schedule;
myWarehouse = warehouse;
spyOn(mySchedule, 'isShopOpen').and.callFake(function() {
return true;
});
spyOn(myWarehouse, 'numAvailableSweets').and.callFake(function() {
return 10;
});
}));
这应该与$ provide机制类似,注意你必须提供注入变量的本地实例来监视。