2014-09-10 112 views
7

我无法让我的单元测试正常工作。我有一个$ scope数组,它开始为空,但应该填充$ http.get()。在现实环境中,会是阵列中的大约15个左右的物体,但对于我的单元测试我只是抓住2.对于单元测试,我有:

expect($scope.stuff.length).toBe(2); 

但茉莉的错误是:预期0为2

这里是我的controller.js:

$scope.stuff = []; 
$scope.getStuff = function() { 
    var url = site.root + 'api/stuff'; 
    $http.get(url) 
     .success(function (data) { 
      $scope.stuff = data; 
     }) 
     .error(function(error) { 
      console.log(error); 
     }); 
}; 

和我controller.spec.js是:

/// <reference path="../../../scripts/angular-loader.min.js" /> 
/// <reference path="../../../scripts/angular.min.js" /> 
/// <reference path="../../../scripts/angular-mocks.js" /> 
/// <reference path="../../../scripts/angular-resource.js" /> 
/// <reference path="../../../scripts/controller.js" /> 
beforeEach(module('ui.router')); 
beforeEach(module('ngResource')); 
beforeEach(module('ngMockE2E')); 
beforeEach(module('myApplication')); 
var $scope; 
var controller; 
var httpLocalBackend; 

beforeEach(inject(function ($rootScope, $controller, $injector) { 
    $scope = $rootScope.$new(); 
    controller = $controller("StuffController", { 
     $scope: $scope 
    }); 
})); 

beforeEach(inject(function ($httpBackend) { 
    httpLocalBackend = $httpBackend; 
})); 

it('should get stuff', function() { 
    var url = '/api/stuff'; 
    var httpResponse = [{ "stuffId": 1 }, { "stuffId": 2 }]; 
    httpLocalBackend.expectGET(url).respond(200, httpResponse); 
    $scope.getStuff(); 
    expect($scope.stuff.length).toBe(2); 
    //httpLocalBackend.flush(); 
}); 

现在,显然,我改变了变量名称等,因为这是为了工作,但希望这是足够的信息,任何人都可以帮助我。如果需要,我可以提供更多。取消注释.flush()一行时,我也会遇到第二个错误,但稍后我会谈谈。

任何帮助非常感谢和提前感谢!

编辑:

终于搞定了!这是我的最终代码:

it('should get stuff', function() { 
    var url = '/api/stuff'; 
    var httpResponse = [{ "stuffId": 1 }, { "stuffId": 2 }]; 
    httpLocalBackend.expectGET(url).respond(200, httpResponse); 
    $scope.getStuff(); 
    httpLocalBackend.flush(); 
    expect($scope.stuff.length).toBe(2); 
}); 

编辑2: 我遇到了另一个问题,我想这可能是这一现象的根本原因。请参阅Unit test failing when function called on startup

+1

您可以尝试在* $ httpBackend.flush()之后放置您期望的*吗? – meriadec 2014-09-10 21:40:00

+1

您需要在预期更改之前刷新它。 – PSL 2014-09-10 21:43:29

回答

7

您需要在expect($ scope.stuff.length).toBe(2)之前放置httpLocalBackend.flush()语句。一旦您提出请求,您需要刷新它以使数据在您的客户端代码中可用。

it('should get stuff', function() { 
    var url = '/api/roles'; 
    var httpResponse = [{ "stuffId": 1 }, { "stuffId": 2 }]; 
    scope.getStuff(); //Just moved this from after expectGET 
    httpLocalBackend.expectGET(url).respond(200, httpResponse); 
    httpLocalBackend.flush(); 
    expect($scope.stuff.length).toBe(2); 
}); 

试试这个。

+0

错误:意外的请求:GET/api /东西 没有更多的预期请求 – Timothy 2014-09-10 21:47:24

+1

我有一个这样的例子: 1)我调用一个函数,这样的事情: $ httpBackend.expect('GET','/ some/url /'+ data) .respond(200,{response_data:false}); 3)然后我做$ httpBackend.flush(); – 2014-09-10 21:51:11

+1

对不起,你也可以尝试在expectGET之前放置scope.getStuff()。这个对我有用。 – 2014-09-10 21:51:57