【问题标题】:Should Angular Service Execute In Unit TestAngular 服务是否应该在单元测试中执行
【发布时间】:2016-06-08 14:29:36
【问题描述】:

我正在尝试将 Karma 和 Jasmine 集成到我的项目中。

我从一个非常基本的测试开始,以确保我的控制器已定义并且 $scope 变量等于一个字符串 - 它按预期通过。

我的控制器也调用了一个执行 $http.get 的服务,在运行我的测试时,没有提及任何服务,我得到了错误:

Error: Unexpected request: GET /my/endpoint/
No more request expected

控制器:

define(['module'], function (module) {
    'use strict';

    var MyController = function ($scope, MyService) {

        $scope.testScope = 'karma is working!';

        MyService.getData().then(function (data) {
            $scope.result = data.hour
        });
    };    

    module.exports = ['$scope', 'MyService', MyController ];
});

测试:

define(['require', 'angular-mocks'], function (require) {
    'use strict';

    var angular = require('angular');

    describe("<- MyController Spec ->", function () {    

        var controller, scope;

        beforeEach(angular.mock.module('myApp'));

        beforeEach(inject(function (_$controller_, _$rootScope_) {
            scope = _$rootScope_.$new();
            controller = _$controller_('MyController', {$scope: scope});  
            scope.$apply();
        }));

        it('should verify that the controller exists ', function() {
            expect(controller).toBeDefined();
        });    

        it('should have testScope scope equaling *karma is working*', function() {
            expect(scope.testScope ).toEqual('karma is working!');
        });
    });
});

是否会出现上述错误?


更新以下回复:

define(['require', 'angular-mocks'], function (require) {
    'use strict';

    var angular = require('angular');

    describe("<- MyController Spec ->", function () {    

        var controller, scope, $httpBackend, myService;

        beforeEach(angular.mock.module('myApp'));

        beforeEach(inject(function (_$controller_, _$rootScope_, _$httpBackend_, _myService_) {
            scope = _$rootScope_.$new();
            $httpBackend = _$httpBackend_;
            $httpBackend.expectGET("/my/endpoint");
            controller = _$controller_('MyController', {$scope: scope});  
            scope.$apply();
        }));

        it('should verify that the controller exists ', function() {
            expect(controller).toBeDefined();
        });    

        it('should have testScope scope equaling *karma is working*', function() {
            expect(scope.testScope ).toEqual('karma is working!');
        });
    });
});

【问题讨论】:

  • 是:您的测试创建了一个控制器实例。您的控制器在实例化时调用您的服务。该服务在调用时会发送一个 HTTP 请求。而且您还没有配置 $httpBackend 来响应这样的请求。所以这个请求确实是出乎意料的。

标签: angularjs unit-testing jasmine karma-jasmine angularjs-service


【解决方案1】:

使用 Angular Mocks,如果尝试了意外或不正确的 http 请求,您总是会收到错误消息——即使对于模板也是如此。在您的情况下,有两种方法可以处理此问题以进行测试:

使用$httpBackend

$httpBackend 旨在测试 http 请求而无需实际连接。在您的测试中,只需添加

$httpBackend.expectGET("/my/endpoint");

在初始化控制器之前。

模拟服务

服务本身正在发出 http 请求,因此您可以改为模拟该服务。服务将照常自动注入,但您可以显式注入任何您想要的:

controller = _$controller_('MyController', {$scope: scope,
MyService: {getData: () => ({then: () => {}}) });  

这会注入一个具有getData 函数的对象,该函数返回一个具有.then 函数的对象。当然,这并不接近于实现您正在尝试做的事情,但它是执行测试的另一种方式。

以上两种方法都有效。这取决于您要测试什么以及您要通过测试完成什么。

【讨论】:

  • 感谢您提供如此详细的答案,我听从了您的建议,并在我的控制器上方添加了上述内容并收到错误:TypeError: 'undefined' is not an object (evalating '$httpBackend.expectGET')
  • 见上面的更新。我收到错误错误:未定义响应!
  • 好的,修好了,需要 .respond([{}, {}, {}]);在 ("/my/endpoint") 的末尾
猜你喜欢
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-11
  • 2017-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多