2016-06-30 103 views
0

我现在有一个项目,我们需要暂时将后端服务器嘲笑,我们正在使用$httpBackend上的应用.run功能。我需要对包含$httpBackend的服务进行单元测试,因为我们将对将要覆盖的服务器进行大量模拟调用。所以现在这就是我所拥有的。作为我的问题的前言,当我从简单页面上的控制器调用mockDataService.getWorkflowTask时,当前设置工作正常。

我的服务器更换服务:

angular.module('app').run(function ($httpBackend, $resource, FakeBackendService) { 
    // TODO: add all necessary http intercepts. 
    $httpBackend.whenGET('JSON file').respond(function (method, url, data) { 
     var request = new XMLHttpRequest(); 
     request.open('GET', url, false); 
     request.send(null); 
     return [request.status, request.response, {}]; 
    }); 
    $httpBackend.whenGET(/.*/).respond(function (method, url, data) { 

     return [200, FakeBackendService.getWorkflowTasks(), {}]; 
    }); 
}); 

这里是FakeBackendService服务:

(function() { 
    'use strict'; 

    var injectParams = []; 

    function service(lodash) { 
     var vm = this; 

     var ret = { 
      getWorkflowTasks: getWorkflowTasks 
     }; 

     function getWorkflowTasks() { 
      if (vm.workflowtasks.length < 1) { 
       vm.workflowtasks = loadWorkflowTasks("Some JSON file"); 
      } 
      return vm.workflowtasks; 
     }; 

     function loadWorkflowTasks(file) { 
      var workflowTasks = []; 
      var request = new XMLHttpRequest(); 
      request.open("GET", file, false); 
      request.send(null); 

      if (request.status == 200) { 
       workflowTasks = angular.fromJson(request.response); 
      } 
      return workflowTasks; 
     }; 

     function init() { 
      vm.workflowtasks = []; 
     } 

     init(); 

     return ret; 
    } 

    service.$inject = injectParams; 
    angular.module('mock.FakeBackendService', []).service('FakeBackendService', service); 
})(); 

所以这是目前后端服务器替换模拟。以下是我的数据处理服务,其中包含对$http.get(blah blah blah)的调用。

(function() { 
    'use strict'; 

    var injectParams = ['$http', '$q', 'mockConfigService', '$httpBackend']; 

    function factory($http, $q, configService, $httpBackend) { 
     var vm = this; 

     var factory = { 
      getWorkflowTask: getWorkflowTask 
     }; 

     function getWorkflowTask(str) { 
      return getResource(str); 
     } 

     function init() { 
      // Get the URL we will be using to get data from 
      vm.dataServiceURL = configService.getDataServiceURL(); 
     } 

     function getResource(baseResource) { 
      var resource = vm.dataServiceURL + baseResource; 

      return $http.get(resource).then(function (response) { 
       if (typeof response.data == 'object') { 
        // Got valid response 
        return $q.resolve(response.data); 
       } 
       else { 
        // Invalid response 
        return $q.reject(response.data); 
       } 
      }, function (response) { 
       // Something went wrong 
       return $q.reject(response.data); 
      }); 
     } 
     init(); 

     return factory; 
    }; 

    factory.$inject = injectParams; 

    angular.module('mock.dataService', []).factory('mockDataService', factory); 
}()); 

现在进行茉莉花 - 噶玛单元测试。

describe("HTTP Backend Mock testing", function() { 

    beforeEach(angular.mock.module("app")); 
    beforeEach(angular.mock.module("mock.FakeBackendService")); 
    beforeEach(angular.mock.module("mock.configService")); 
    beforeEach(angular.mock.module("mock.dataService")); 

    it("Get the workflow task", angular.mock.inject(function (mockDataService) { 
     var valid = ""; 

     var promise = mockDataService.getWorkflowTask('http://localhost/foo'); 

     promise.then(function (response) { 
      valid = "Success"; 
     }, function (response) { 
      valid = "Failure"; 
     }); 

     expect(valid).toBe("Success"); 
    })); 
}); 

现在的问题。所以,我会首先说我是AngularJS世界的新手,对Jasmine更是如此。无论如何,当我调试单元测试时,我发现承诺的状态仍然为0,并且我总是期望成为'成功',告诉我我永远不会解决(希望我使用正确的术语)$http服务的承诺在mockDataService。我尝试过试玩一些,试图看看有没有人以前做过这种事情。我发现很多例子,其中$httpBackend在测试中被嘲笑,但没有人喜欢我正在尝试的东西。任何想法或建议都会很棒。谢谢。

编辑得到一个稍微工作液

所以我决定,我会通过通过run()服务,只是做在expectGET().respond()同样的反应。

describe("HTTP Backend Mock testing", function() { 
    beforeEach(angular.mock.module("app")); 
    beforeEach(angular.mock.module("mock.FakeBackendService")); 
    beforeEach(angular.mock.module("mock.configService")); 
    beforeEach(angular.mock.module("mock.dataService")); 

    it("Get the workflow task", angular.mock.inject(function (mockDataService, $httpBackend, FakeBackendService) { 
     var valid = ""; 
     $httpBackend.expectGET('http://server:80/api/foo').respond(200, FakeBackendService.getWorkflowTasks()); 
     var promise = mockDataService.getWorkflowTask('foo'); 


     promise.then(function (response) { 
      valid = "Success"; 
     }, function (response) { 
      valid = "Failure"; 
     }); 
     $httpBackend.flush(); 

     expect(valid).toBe("Success"); 
    })); 
}); 

这种解决我与run()测试问题为目标是验证1)这正则表达式匹配调用正确的FakeBackendService2)FakeBackendService返回正确的文件和实际加载它。我想我可以通过在expectGET中模仿相同的正则表达式来做到这一点。但是,我会留下一点看看是否有人知道如何让run()工作。

回答

1

承诺不会解决,除非您在测试结束前强制这样做。这里有一个这样的方法:

$httpBackend.expectGET(......).respond(200, 'abc'); 

    var promise = mockDataService.getWorkflowTask('http://localhost/foo'); 

    promise.then(function (response) { 
     valid = "Success"; 
    }, function (response) { 
     valid = "Failure"; 
    }); 

    //new code here 
    $httpBackend.flush(); 

    expect(valid).toBe("Success"); 

这将迫使承诺解决,你的测试应该通过。您还需要将$ httpBackend服务注入测试。

+0

我试过,我得到错误:意外的请求:GET HTTP://等等等等没有更多的要求预计 – DarkLazar

+0

进步......现在给你打电话mockDataService.getWorkflowTask(前... ..)把一个$ httpBackend.expectGET(等等等等等等); – Austin

+0

我欣赏它奥斯汀,我试过了,我得到错误:没有反应定义! – DarkLazar

0

angular.module('mock.dataService', []) 
 
    .service('mockDataService', function($http) { 
 
    this.getWorkflowTask = function(url) { 
 
     return $http.get(url) 
 
    } 
 
    }) 
 

 
describe('HTTP Backend Mock testing', function() { 
 
    var $httpBackend 
 
    beforeEach(angular.mock.module("mock.dataService")); 
 
    beforeEach(inject(function(_$httpBackend_) { 
 
    $httpBackend = _$httpBackend_ 
 
    })) 
 

 
    it("Get the workflow task", angular.mock.inject(function(mockDataService) { 
 
    $httpBackend.expectGET('http://localhost/foo').respond(200); 
 

 
    var promise = mockDataService.getWorkflowTask('http://localhost/foo'); 
 

 
    promise.then(function(response) { 
 
     valid = "Success"; 
 
    }, function(response) { 
 
     valid = "Failure"; 
 
    }); 
 

 
    $httpBackend.flush(); 
 

 
    expect(valid).toBe("Success"); 
 
    })); 
 
})
<link href="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" /> 
 
<script src="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-mocks.js"></script>