Karma-Jasmine:如何正确测试 http 调用?

Karma-Jasmine: How to properly test http calls?

情况:

我需要测试一个 http 调用并确保它被正确调用。

在应用程序中一切正常:$scope.language_list 从 api

正确检索数据

但在测试中 $scope.language_list 未定义。 所以可能我没有做正确的测试。

代码:

函数:

$scope.get_language_list = function()
{
    $http.get('http://my_app.org/languageList')
    .success(function(data, status, headers, config) 
    {
        $scope.language_list = data;
        $scope.valid = true;

    })
    .error(function(data, status, headers, config) 
    {
        $scope.valid = false;
    });
}

测试:

describe('Http calls test', function() {

    beforeEach(module('my_app.controllers'));

    beforeEach(inject(function(_$controller_, _$httpBackend_) 
    {
        $scope = {};
        var controller = $controller('MainCtrl', { $scope: $scope });

        $httpBackend = _$httpBackend_;
        $httpBackend.whenGET('http://my_app.org/languageList').respond(200);

    }));

    it('should load default language list', function() 
    {
        $httpBackend.flush();

        console.log($scope.language_list);

        expect($scope.valid).toBe(true);
        expect($scope.language_list).not.toEqual(undefined);
    });


});

结果:

$scope.valid 测试正常。如果我故意在函数中更改它的值以查看测试失败,它确实会失败,否则会正确传递为 true。

但是 $scope.language_list 没有正常工作,并且作为未定义传递。实际上错误信息是:Expected undefined not to equal undefined.

问题:

如何正确测试 http 调用? 为什么 $scope.language_list 是未定义的?我在测试中做错了什么?

非常感谢!

您需要提供一个模拟响应对象。当前,成功函数中的 "data" 参数未定义。要定义响应:

beforeEach(inject(function(_$controller_, _$httpBackend_) 
{
    $scope = {};
    var controller = $controller('MainCtrl', { $scope: $scope });

    $httpBackend = _$httpBackend_;

    //Tell the $httpBackend to respond with our mockLangularList array. Or whatever the api actually returns.Array used for example.
    var mockLanguageList = [{key: ''},{key: ''},{key: ''}];
    $httpBackend.whenGET('http://my_app.org/languageList').respond(200, mockLanguageList);

}));

此外,你每次都调用 $scope.get_language_list() 吗?

it('should load default language list', function() 
{
    $scope.get_language_list(); // <-- Make call
    $httpBackend.flush();

    console.log($scope.language_list);

    expect($scope.valid).toBe(true);
    expect($scope.language_list).not.toEqual(undefined);
});