Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 当使用jasmine进行单元测试时,如何在AngularJS中模拟服务?_Unit Testing_Angularjs_Jasmine - Fatal编程技术网

Unit testing 当使用jasmine进行单元测试时,如何在AngularJS中模拟服务?

Unit testing 当使用jasmine进行单元测试时,如何在AngularJS中模拟服务?,unit-testing,angularjs,jasmine,Unit Testing,Angularjs,Jasmine,假设我有一个服务商店,它依赖于两个有状态的服务时间表和仓库。如何将不同版本的schedule和warehose注入shop进行单元测试 这是我的服务: angular.module('myModule').service('shop', function(schedule, warehouse) { return { canSellSweets : function(numRequiredSweets){ return schedule.isSh

假设我有一个服务
商店
,它依赖于两个有状态的服务
时间表
仓库
。如何将不同版本的
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);

你可以在这里查看更多信息

您希望利用$provide服务。就你而言

$provide.value('schedule', mockSchedule);

模块是由“角度模拟”模块提供的功能。如果您传入一个字符串参数,则会加载一个具有相应名称的模块,并且所有提供程序、控制器、服务等都可用于规范。通常,它们是使用inject函数加载的。如果传入回调函数,将使用Angular的$injector服务调用它。然后,该服务查看传递给回调函数的参数,并尝试推断应该将哪些依赖项传递给回调函数

对于CoffeeScript,我遇到了一些问题,因此我在结尾使用了null

beforeEach ->
  module ($provide) ->
    $provide.value 'someService',
      mockyStuff:
        value : 'AWESOME'
    null

改进Atilla的回答并直接回答KevSheedy的评论,在
模块('myApplicationModule')
的上下文中,您将执行以下操作:

beforeEach(module('myApplicationModule', function ($provide) {
  $provide.value('schedule', mockSchedule);
}));

我最近发布了ngImprovedTesting模块,该模块将使AngularJS方式的模拟测试更容易

在您的示例中,您只需在Jasmine测试中替换

beforeEach(module('myModule'));
。。。与

beforeEach(ModuleBuilder.forModule('myModule').serviceWithMocks('shop').build());
有关ngImprovedTesting的更多信息,请查看其介绍性博文:

在模块上放置模拟更简单,如下所示:

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

当您使用jasmine时,有另一种方法可以用jasmine的间谍来模拟呼叫()

使用这些函数,您可以成为函数调用的目标,并在需要时允许调用原始对象。它避免了用$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;
  });

}));

这应该以与$PROFECT机制类似的方式工作,注意您必须提供注入变量的本地实例来监视。

为了避免cooffeescript隐式返回,您只需在函数末尾添加一个
return
语句,因此,函数不返回
null
,而只是不返回任何内容。看,如果你说“return”,它将返回“undefined”--但这两种方法都可以很好地工作,而且这种方法短2个字符;)--不管是哪种方式,你都应该在这条线上添加一条评论,因为无意中删除它的那个家伙正遭受着与你当初一样的痛苦。这修复了我的(令人沮丧的)问题。基本上,只要我添加$provideformocking,我的angular.mock.inject就不再运行/工作。返回null使它们可以很好地配合使用。因此,这种语法基本上可以模拟
myApplicationModule
中的
时间表(或任何服务、控制器、工厂)?您真的需要额外的周边函数吗?也就是说,是否可以在每次调用之前将
模块
函数直接传递到
?实际上不需要围绕
模块
调用的函数。
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;
  });

}));