如何为使用API​​和回调的跟随角度服务编写茉莉花测试

时间:2015-06-10 20:41:11

标签: angularjs callback jasmine

在我的AngularJS应用程序中,我无法弄清楚如何对以下代码进行单元测试:

这是我的测试控制器使用的服务:

angular
    .module('web.template')
    .factory('testService', testService);

testService.$inject = ['$http'];

function testService($http) {
   return { 
        getTestDatas: function (callback) {
        var data = {
            'testParams': "test"
        };

        $http.post('http://localhost/test/post', data)
            .success(function (response) {
                callback(response);
            });
        },
    };
};

1 个答案:

答案 0 :(得分:0)

docs中所述,您可以使用$httpBackend$http进行模拟。

您可以测试实现服务的两种方式(回调或承诺)。但我也认为承诺更适合测试,应该是首选。

只需在您的依赖项中包含ngMock,然后就可以为您的网址创建虚假回复。

请查看下面的演示(不在SO上工作,需要检查问题所在)或jsFiddle

的工作演示



angular
    .module('web.template', ['ngMock'])
    .controller('mainCtrl', MainCtrl)
    .factory('testService', testService);

testService.$inject = ['$http'];

function testService($http) {
   return { 
        getTestDatas: function (callback) {
        var data = $.param({ // $.param for jsfiddle
            json: JSON.stringify({ // json wrapper just for jsfiddle
                testParams: 'test'
            }),
            delay: 1
        });

        return $http.post('/echo/json/', data)
            .success(function (response) {
                console.log(response);
                callback ? callback(response): undefined;
            });
        },
    };
};

function MainCtrl($scope, testService) {
    
    var getDataCb = function(response) {
        $scope.data = response;
    };
    
    testService.getTestDatas(getDataCb);
    
}

MainCtrl.$inject = ['$scope', 'testService'];

// specs code
describe("Test suite for $http service", function() {
  
  var $httpBackend, $rootScope, $testService;

   // Set up the module
   beforeEach(module('web.template'));

   beforeEach(inject(function($injector) {
     // Set up the mock http service responses
     $httpBackend = $injector.get('$httpBackend');
     // backend definition common for all tests
     var fakedMainResponse = {testParams: 'testMocked' };
     $httpBackend.when('POST', '/echo/json/').respond(fakedMainResponse);
     //authRequestHandler = $httpBackend.when('GET', '/echo/json/')
     //                       .respond({testParams: 'testMocked' });

     $testService = $injector.get('testService');
     // Get hold of a scope (i.e. the root scope)
     $rootScope = $injector.get('$rootScope');
     // The $controller service is used to create instances of controllers
     //var $controller = $injector.get('$controller');

     //createController = function() {
     //  return $controller('MyController', {'$scope' : $rootScope });
     //};
   }));


   afterEach(function() {
     $httpBackend.verifyNoOutstandingExpectation();
     $httpBackend.verifyNoOutstandingRequest();
   });
    
  it("server should return test value with callback", function() {
      
    //expect(true).toBe(false);
      $testService.getTestDatas(function(response) {
          console.log('testing service', response);
          expect(response).toEqual({"testParams": "testMocked"});
          //expect(true).toBe(false);
      });
      $httpBackend.flush();
  });
    
  it("server should return test value with promise", function() {
      
    //expect(true).toBe(false);
      $testService.getTestDatas(undefined).then(function(response) {
          expect(response.data).toEqual({"testParams": "testMocked"});
      });
      $httpBackend.flush();
  });

});

// load jasmine htmlReporter
(function() {
  var env = jasmine.getEnv();
  env.addReporter(new jasmine.HtmlReporter());
  env.execute();
}());

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.16/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.16/angular-mocks.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<script src="http://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="http://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>
<link href="http://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css" rel="stylesheet"/>
<div ng-app="web.template" ng-controller="mainCtrl"><pre>{{data|json}}</pre></div>
&#13;
&#13;
&#13;