【问题标题】:Handling AJAX Post Request Callbacks in Jasmine Unit Test在 Jasmine 单元测试中处理 AJAX 发布请求回调
【发布时间】:2015-10-21 18:55:17
【问题描述】:

我已经尝试设置这个测试很长时间了......我真的不明白这里有什么不工作。

我的 Angular 应用:

<body ng-app="testApp">
<div class="container" droppable>
    <div class="row"><navi></navi></div>
    <div class="row">
            <div class="col-xs-8">
                <preview></preview>
                <editor></editor>
            </div>
            <div class="col-xs-4">
                <iframe src="" pull-down></iframe>
            </div>
    </div>
</div>

控制器:

testApp.controller('previewController', ['$scope', '$http', function($scope, $http) {
$scope.tmp = "test";
console.log("init controller");
$.ajax({
    url: "http://localhost/angularjs_testapp/request.php",
    type: "POST",
    success: function(data){
        console.log("server data:");
        console.log(data);
        $scope.data = data;},
    error: function(data){
        console.log("error occured");
        console.log(data);
    }
});
}]);

至少还有测试:

describe('previewController', function() {
beforeEach(module('testApp'));
var scope, createController;

beforeEach(inject(function ($rootScope, $controller) {
    scope = $rootScope.$new();

    createController = $controller('previewController', {
            '$scope': scope
        });
}));

it('should be "test":', function(done) {
    console.log(scope);
    expect(scope.tmp).toBe("test");  //working
    expect(scope.data).toBe("hallo"); //not working
});
});

如果我只是在网站上调用它,服务器会正​​确返回 ajax 返回值。但是在测试环境之外它不起作用。似乎他没有与服务器通信。我也做了一个承诺,还尝试了 $http.post() 而不是 ajax 来解决它,但它仍然无法正常工作。我究竟做错了什么?业力引擎是否会导致服务器通信失败?

【问题讨论】:

  • 您是否要进行完整的集成测试?还是您只需要像常规单元测试一样验证通信是否发生?
  • 我要验证服务器通信,仅此而已
  • 那是 Angular 中的 jQuery 的 ajax 方法吗?使用 $http!然后就可以使用 $httpBackend 来控制了。
  • 我已经尝试过了——同样的错误

标签: javascript ajax angularjs karma-jasmine


【解决方案1】:

所以您遇到的问题是您试图在解决之前查看$promise 的结果。这意味着您必须更改一些内容,包括使用$http。由于这是一个单元测试而不是集成测试,因此您希望使用 $httpBackend 来消除您的通信,因此您实际上不需要后端服务器。

所以您的更改需要:

//in your controller
testApp.controller('previewController', ['$scope', '$http', function($scope, $http) {
     $scope.tmp = "test";
     $http.post("http://localhost/angularjs_testapp/request.php",{})
.success function(data){
    console.log("server data:");
    console.log(data);
    $scope.data = data;}).
error(function(data){
    console.log("error occured");
    console.log(data);
    })
}]);   

//in your jasmine tests
describe('previewController', function() {
beforeEach(module('testApp'));
var scope, createController, httpBackend;

beforeEach(inject(function ($rootScope, $controller, $httpBackend) {
    scope = $rootScope.$new();
    httpBackend = $httpBackend;
    httpBackend.expectPOST("http://localhost/angularjs_testapp/request.php",{}).respond(200,{...Your Response...});
    createController = $controller('previewController', {
        '$scope': scope
    });

}));
afterEach(function () {
         httpBackend.verifyNoOutstandingExpectation();
         httpBackend.verifyNoOutstandingRequest();
});
it('should be "test":', function(done) {
    console.log(scope);
    expect(scope.tmp).toBe("test");  //working
    httpBackend.flush();
    expect(scope.data).toBe("hallo"); //not working
});
});

【讨论】:

  • 嘿,为你的答案加油!但现在我再次收到TypeError: httpBackend.expectPost is not a function
  • 更新了这是一个错字,应该是expectPOST
  • 好的,它现在似乎工作得更好了,但仍然没有真正工作:Expected Object({ hallo: 'hallo' }) to be Object({ hallo: 'hallo' }). ??为什么会失败?就像failed comparing 1=1 ...
  • 在这种情况下,您使用的是 ToBe 与 ToEqual,因为 ToBe 等价于 === 而 toEqual 是 == jasmine.github.io/2.0/…
  • stackoverflow.com/questions/22604644/… 。我已经让你的代码保持原样,但如果你看起来你的 it 函数块中有一个 done 参数,它从未使用过。结果茉莉很生气。因此,如果您不需要它,只需摆脱 done。
猜你喜欢
  • 2014-10-31
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 2018-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-23
相关资源
最近更新 更多