如何在使用茉莉花进行unit testing时在AngularJS中模拟一项服务?
比方说,我有一个服务shop
,取决于两个有状态的服务schedule
和warehouse
。 如何将不同版本的schedule
和warehose
注入unit testing的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}; }
这是我的testing:
expect(shop.canSellSweets(5)).toBe(true); expect(shop.canSellSweets(20)).toBe(false);
beforeEach(function () { module(function ($provide) { $provide.value('schedule', mockSchedule); }); });
模块是angular度模拟模块提供的function。 如果传入一个string参数,则会加载一个相应名称的模块,并且所有提供者,控制器,服务等都可用于该规范。 一般来说,它们是使用注入函数加载的。 如果你传入一个callback函数,它将被使用Angular的$注入器服务来调用。 然后,该服务将查看传递给callback函数的参数,并尝试推断应将哪些依赖项传递到callback函数中。
改进Atilla的答案,并直接回答KevSheedy的评论,在module('myApplicationModule')
的上下文中,您将执行以下操作:
beforeEach(module('myApplicationModule', function ($provide) { $provide.value('schedule', mockSchedule); }));
使用CoffeeScript我运行在一些问题,所以我在最后使用null :
beforeEach -> module ($provide) -> $provide.value 'someService', mockyStuff: value : 'AWESOME' null
你可以在这里find更多的信息
https://docs.angularjs.org/guide/services#unit-testing
你想利用$提供服务。 在你的情况
$provide.value('schedule', mockSchedule);
我最近发布了ngImprovedTesting模块,这个模块应该可以让模拟testing更容易。
在你的例子中,你只需要在你的茉莉花testing中取代…
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/
把模拟放在这个模块上是比较简单的:
beforeEach(function () { module('myApp'); module({ schedule: mockSchedule, warehouse: mockWarehouse } }); });
你可以使用注入来获得这些模拟预处理操作的参考:
var mockSchedule; var mockWarehouse; beforeEach(inject(function (_schedule_, _warehouse_) { mockSchedule = _schedule_; mockWarehouse = _warehouse_; }));
我希望我的回答不是没用,但你可以通过$provide.service
来模拟服务
beforeEach(() => { angular.mock.module( 'yourModule', ($provide) => { $provide.service('yourService', function() { return something; }); } ); });
当你使用茉莉花,有茉莉的间谍嘲笑电话的另一种方法( https://jasmine.github.io/2.0/introduction.html#section-间谍)。;
使用这些,你可以作为你的函数调用的目标,并允许在需要时调用原始对象。 它避免了用$ provide和mock实现堵塞testing文件的顶部。
在你的testing之前,我会有这样的东西:
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; }); }));
这应该与$提供机制类似,注意你必须提供注入variables的本地实例来监视。