如何在使用茉莉花进行unit testing时在AngularJS中模拟一项服务?

比方说,我有一个服务shop ,取决于两个有状态的服务schedulewarehouse 。 如何将不同版本的schedulewarehose注入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的本地实例来监视。