如何为依赖于工厂服务的控制器编写单元测试,工厂服务本身依赖于$ http服务

时间:2016-02-12 01:33:24

标签: angularjs unit-testing karma-jasmine

我正在努力了解如何使用Jasmine和Karma对一个简单的应用AngularJS进行单元测试。我试过谷歌搜索,但没有在我自己的代码上取得任何进展。特别是围绕模拟和注入依赖于内置$ http服务的工厂服务。

此外,对控制器和工厂服务进行单元测试是好的做法,或者其中一个是足够的。

我已将代码上传到plunkr并希望得到任何帮助

https://plnkr.co/edit/WBpJ7gUZrNm8LwnCOsnR

factory.main.js

angular.module('hwApp').factory('mainFactory', ['$http', function($http){
  return {
     getData: function(){
       return $http.get('https://jsonplaceholder.typicode.com/posts/1');
     }
  }
}]);

controller.main.js

angular.module('hwApp').controller('MainCtrl', ['mainFactory', function(mainFactory){
  vm = this;
  mainFactory.getData().then(function(res){
    vm.httpData = res.data;
  })
}]);

的index.html

<!DOCTYPE html>
<html ng-app="hwApp">

  <head>
    <script data-require="angular.js@1.5.0" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
    <script src="factory.main.js"></script>
    <script src="controller.main.js"></script>
  </head>

  <body ng-controller="MainCtrl as vm">
    <h1>{{vm.httpData.title}}</h1>
  </body>
</html>

1 个答案:

答案 0 :(得分:4)

通常,您将单独对控制器和服务进行单元测试。 Pluralsight有一个很好的课程,使用ngMock对控制器和服务进行单元测试。我建议找一些可以引导您完成的教程,但我可以为您提供一个例子,说明您在测试工厂时所寻找的内容。

单元测试您的工厂

describe("your backend service", function () {
  var dataWeWantToGet = [ "put", "your", "data", "here" ]; 
  var mainFactory;
  var $httpBackend;

  beforeEach(angular.mock.module("hwApp"));

  beforeEach(inject(function (_mainFactory_, _$httpBackend_) {
    mainFactory = _mainFactory_;
    $httpBackend = _$httpBackend_;
  }));


  it("should return movie search data from the title", function() {
    var response = [];

    $httpBackend.when('GET', 'https://jsonplaceholder.typicode.com/posts/1')
      .respond(200, dataWeWantToGet);

    mainFactory.getData()
      .then(function onSuccess(data) {
        response = data;
      });

    $httpBackend.flush();

    expect(response.data).toEqual(dataWeWantToGet);
  }); // end it

}); // end describe

在这个例子中,我们将模拟后端和控制器中发生的代码。这种隔离对于证明您的工厂独立于您的控制器是必要的。

控制器怎么样?

在测试控制器时,您希望实现类似的隔离,但我认为您是否需要通过控制器测试服务的功能是值得商榷的。你几乎就是那样做的。要对控制器的那部分进行单元测试,您必须注入刚刚测试过的服务并以您刚刚测试的方式使用它在您工厂的单元测试中。

这就是测试多少以及开始引起争议的问题?就个人而言,我不知道我是否会在控制器中使用它来测试服务。我会测试那些受它影响的东西是否正确更新。在Angular,这通常是更大的挑战。我很乐意听取别人的意见。