javascript - Angularjs 测试返回静态数据的简单工厂

标签 javascript angularjs jasmine karma-runner

如何在 AngularJs 中模拟一个简单的 Factory,它在 Karma 单元测试中返回静态数据?

我有这个简单的工厂,为了举例返回静态数据:

angular.module('conciergeApp.services')
       .factory('CurrentUser', function() {
        return {
            id: 1,
            hotel_id: 1,
        }
      });

我想知道如何为此编写一个 Karma 测试?

到目前为止,我有这段代码,但 id 不起作用:

describe('ReplyCtrl', function() {

    beforeEach(module('conciergeApp'));

    beforeEach(module(function($provide) {
        $provide.service('CurrentUser', function() {
            return 1;
        });
    }));

    //Getting reference of the mocked service
    var mockUtilSvc;

    inject(function(CurrentUser) {
        mockUtilSvc = CurrentUser;
    });

    beforeEach(inject(function($rootScope, $controller) {
        scope = $rootScope.$new();
        ctrl = $controller('ReplyCtrl', {
            $scope: scope
        });
    }));

    it('should return value from mock dependency', inject(function(mockUtilSvc) {
        expect(mockUtilSvc()).toEqual(1);
    }));

});

这是我收到的错误消息:

Firefox 41.0.0 (Mac OS X 10.10.0) ReplyCtrl should return value from mock dependency FAILED
    Error: [$injector:unpr] Unknown provider: mockUtilSvcProvider <- mockUtilSvc

最佳答案

1) 你在错误的地方有inject。您正在测试 it 中指定注入(inject)函数,只需将其删除即可。

it('should return value from mock dependency', inject(function(mockUtilSvc) {
    expect(mockUtilSvc()).toEqual(1);
}));

会变成

 it('should return value from mock dependency', function() {
    expect(mockUtilSvc()).toEqual(1);
});

2) 现在的问题是 mockUtilSvc 是一个服务实例,而不是您定义的函数,同样根据您的模拟,您需要将其定义为工厂(即您返回 1 作为factory 的值,它不是 new able)。

beforeEach(module(function($provide) {
    $provide.factory('CurrentUser', function() {
        return 1;
       //If you expect factory to be a function then you need to return a function returning 1 here
    });
}));

expect(mockUtilSvc).toEqual(1);

3) 你也可以这样写:

$provide.value('CurrentUser', 1); //Provide the instance here right away

4) 你的第一个inject 也放错了地方。您只是在运行它,而不是在每次规范运行期间运行和分配实例。 在每次 迭代之前,您需要将服务实例的值设置为您的变量,即:

 beforeEach(inject(function(CurrentUser) {
    mockUtilSvc = CurrentUser;
}));

示例测试:

describe('ReplyCtrl', function() {
   var mockData = {
            id: 1234,
            hotel_id: 1,
        }, mockUtilSvc, scope, ctrl  ;


    beforeEach(module('conciergeApp', function($provide) {
        $provide.value('CurrentUser', mockData);
    }));

    beforeEach(inject(function(CurrentUser, $rootScope, $controller) {
        mockUtilSvc = CurrentUser;
        scope = $rootScope.$new();
        ctrl = $controller('ReplyCtrl', {
            $scope: scope
        });
    }));

    it('should return value from mock dependency', function() {
        expect(mockUtilSvc.id).toEqual(mockData.id);
    });
});

Demo

注意:还有其他方法可以模拟和注入(inject)模拟。例如,在这种情况下,您实际上也不需要使用 $provide.value。相反,您可以创建模拟对象并在 Controller 实例化期间将其传入,因为您可以完全控制那里以传递依赖项,如下所示:

  ctrl = $controller('ReplyCtrl', {
            $scope: scope,
            CurrentUser: mockUtilSvc
   });

在使用方法的更复杂服务的情况下,您可以像这样创建模拟。

  mockSvc = jasmin.createSpyObj('MyService', ['method1', 'method2']);
  mockSvc.method1.and.returnValue($q.when(mockData)); //Simulating a promise returned from an $http call  in the method.

关于javascript - Angularjs 测试返回静态数据的简单工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33468458/

相关文章:

angularjs - Uncaught Error : Template parse errors: Can't bind to 'columnMode' since it isn't a known property of 'ngx-datatable'

angularjs - Angular 过滤器正好位于对象键上

gruntjs - 配置 jasmine-jquery 以使用 Karma

javascript - 未捕获的类型错误 : Cannot read property 'attributes' of undefined

javascript - 如何测试元素(标签)是否用 jest/enzyme 渲染?

javascript - 如何访问 React props 中的嵌套对象属性

javascript - Socket.io 向房间广播在 socket.io v.0.9.13 中不起作用

javascript - Coffeescript 类中的方法返回函数而不是字符串

angularjs - $httpBackend 没有 stub 请求/响应?

php - Ajax 登录和 javascript cookie,这安全吗?