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

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

问题描述:

假设我有一个服务 shop,它依赖于两个有状态服务 schedulewarehouse.如何将不同版本的 schedulewarehose 注入 shop 进行单元测试?

Let's say I have a service shop that depends on two stateful services schedule and warehouse. How do I inject different versions of schedule and warehose into shop for unit testing?

这是我的服务:

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

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

Module 是 angular-mocks 模块提供的一个函数.如果传入字符串参数,则会加载具有相应名称的模块,并且所有提供者、控制器、服务等都可用于规范.通常它们是使用注入功能加载的.如果您传入回调函数,它将使用 Angular 的 $injector 服务调用.然后,该服务查看传递给回调函数的参数,并尝试推断应将哪些依赖项传递到回调中.

Module is a function provided by the angular-mocks module. If you pass in a string argument a module with the corresponding name is loaded and all providers, controllers, services, etc are available for the spec. Generally they are loaded using the inject function. If you pass in a callback function it will be invoked using Angular's $injector service. This service then looks at the arguments passed to the callback function and tries to infer what dependencies should be passed into the callback.