【问题标题】:$httpBackend in AngularJs Jasmine unit testAngularJs Jasmine 单元测试中的 $httpBackend
【发布时间】:2014-09-10 21:34:54
【问题描述】:

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

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

但是 jasmine 的错误是:Expected 0 to be 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

【问题讨论】:

  • 你可以尝试把你期望的放在 $httpBackend.flush() 之后吗?
  • 您需要在期待更改之前刷新它。

标签: javascript angularjs unit-testing jasmine


【解决方案1】:

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

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);
} );

试试这个。

【讨论】:

  • 错误:意外请求:GET /api/stuff 不再有请求
  • 我有一个像这样工作的例子:1)我调用一个函数发出 get 请求,例如 scope.functionThatMakesAGetRequest() 2)然后我有这样的东西: $httpBackend.expect('GET ', '/some/url/'+data) .respond(200, {response_data: false}); 3) 然后我做 $httpBackend.flush();
  • 抱歉,您也可以尝试将 scope.getStuff() 放在 expectGET 之前吗?它对我有用。
  • 我仍然遇到同样的错误。我确实将expectGET更改为whenGET,现在我得到的唯一错误是“没有待处理的刷新请求!”但我不确定这是前进还是后退..
  • 我把它改回了expectGET,并将对函数的调用移回到expectGET之后。所以,expectGET,调用函数,flush,expect(whatever).toBe(whatever)。我会用新代码更新我的问题,然后将你的答案标记为已接受,因为没有你我不会得到它。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 2013-10-06
  • 1970-01-01
相关资源
最近更新 更多