angularjs – 如何测试控制器内服务的响应

前端之家收集整理的这篇文章主要介绍了angularjs – 如何测试控制器内服务的响应前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试测试在控制器中执行的服务http调用的响应:

控制器:

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

    var MyController = function ($scope,MyService) {

        var vm = this;

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

        MyService.getData().then(function (data) {
            $scope.result = data.hour
            vm.banner = {
                'greeting': data.greeting
            }
        });
    };    

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

单元测试:

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

var angular = require('angular');

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

    var controller,scope,myService,serviceResponse;

    serviceResponse= {
        greeting: 'hello',hour: '12'
    };

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

    beforeEach(inject(function (_$controller_,_$rootScope_,_MyService_,$q) {
        scope = _$rootScope_.$new();
        var deferred = $q.defer();
        deferred.resolve(serviceResponse);

        myService = _MyService_;
        spyOn(myService,'getData').and.returnValue(deferred.promise);

        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请求的执行并返回绑定到$scope.result和vm.banner问候语的serviceResponse

我试过了:

define(['require',serviceResponse,$httpBackend;

    serviceResponse= {
        greeting: 'hello',_$httpBackend_) {
        scope = _$rootScope_.$new();
        $httpBackend = _$httpBackend_

        $httpBackend.expectGET("/my/endpoint/here").respond(serviceResponse);

        myService = _MyService_;
        spyOn(myService,'getData').and.callThrough();

        controller = _$controller_('MyController',{$scope: scope});  
        scope.$apply();
    }));

    it('should call my service and populate scope.result ',function() {
        myService.getData();
        expect(scope.result ).toEqual(serviceResponse.hour);
    });

    it('should verify that the controller exists ',function() {
        expect(scope.testScope ).toEqual('karma is working!');
    });
});
});

错误

[should call my service and populate scope.result -----     Expected undefined to be defined.

解决方法

我所理解的是,在期待结果时,你已经制作了一个Ajax&在promise得到解决时设置数据值.

基本上当你在控制器实例化时调用myService.getData()方法时,它会执行一个$http,它将间接执行$httpBackend ajax并从中返回mockData.但是一旦你拨打电话,你就不会等待电话那个完成电话.那么你正在调用你的断言语句,这会使你的statte失败.

请查看下面的代码注释以获得解释

it('should call my service and populate scope.result ',function() {
   //on controller instantiation only we make $http call
   //which will make your current execution state of your code in async state
   //and javascript transfer its execution control over next line which are assert statement
   //then obivIoUsly you will have undefined value.
   //you don't need to call below line here,as below method already called when controller instantiated
   //myService.getData();
   //below line gets called without waiting for dependent ajax to complete.
   expect(scope.result ).toEqual(serviceResponse.hour);
});

所以现在你理解你需要告诉我们的测试代码,我们需要等待ajax调用结束时执行assert语句.所以为此你可以使用$httpBackend.flush()方法,在这种情况下,这将有助于你.在将控制传递给下一行之前,它将清除所有$httpBackend调用队列清除.

it('should call my service and populate scope.result ',function() {
   $httpBackend.flush();// will make sure above ajax code has received response
   expect(scope.result ).toEqual(serviceResponse.hour);
});

猜你在找的Angularjs相关文章