【问题标题】:Karma-Jasmine: Unexpected request: GET ... No more request expectedKarma-Jasmine:意外请求:GET ... 预计不再有请求
【发布时间】:2016-01-17 18:41:03
【问题描述】:

情况:

我正在我的 AngularJs 应用程序中测试两个不同的 http 调用。

有一个奇怪的行为。如果我分别测试每个,另一个临时注释掉(在控制器和测试中)每个都可以正常工作并且测试通过。

但是如果我在两个测试都运行 karma 时,它们会失败,并给出以下错误消息:

Unexpected request: GET https://MY_DOMAIN_2.com/list_project
No more request expected

控制器:

.controller('TestController', function($scope, $http, $timeout) {

    $scope.getLanguageList = function()
    {
        $http.get('http://MY_DOMAIN_1.org/languageList').then(function(resp) 
        {
            $scope.language_list = resp.data;
        }, 
        function(err) 
        {
            $scope.language_list = [];
        })
    }

    $scope.language_list = [];
    $scope.getLanguageList();


    $scope.get_project_list = function()
    {
        $http.get('https://MY_DOMAIN_2.com/projectList').then(function(resp) 
        {
            $scope.project_list = resp.data;
        }, 
        function(err) 
        {
            $scope.project_list = [];
        })
    }

    $scope.project_list = [];
    $scope.get_project_list();

})

测试:

describe('Http requests tests', function() {

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

var $controller;
var $httpBackend;
var $scope;
var $timeout;


describe('Lists test', function() 
{

    beforeEach(angular.mock.http.init);
    afterEach(angular.mock.http.reset);

    beforeEach(inject(function(_$controller_, _$httpBackend_) 
    {
        $controller = _$controller_;
        $scope = {};
        $httpBackend = _$httpBackend_;

    }));


    it('should load default language list', function (done) 
    {
        $httpBackend.whenGET('http://MY_DOMAIN_1.org/languageList').passThrough();

        var TestController = $controller('TestController', { $scope: $scope });

        setTimeout(function() 
        {
            expect($scope.language_list).not.toEqual([]);
            done();
        }, 1000);

    });


    it('should load default project list', function (done) 
    {
        $httpBackend.whenGET('https://MY_DOMAIN_2.org/projectList').passThrough();

        var TestController = $controller('TestController', { $scope: $scope });

        setTimeout(function() 
        {
            expect($scope.project_list).not.toEqual([]);
            done();
        }, 1000);

    });

});

});

问题:

为什么我会收到该错误消息? 代码应该没问题,因为它们分别工作正常。我错过了什么吗?

谢谢!

【问题讨论】:

  • 如果您将 $scope = {} 更改为 $scope = $rootScope.$new() 会怎样?
  • 已尝试但没有任何改变。

标签: javascript angularjs unit-testing karma-runner karma-jasmine


【解决方案1】:

这里有一些提示和演示http://plnkr.co/edit/Kp9C4S6oNVu1MM1YLb90?p=preview

  • 您应该使用$httpBackend.flush() 而不是setTimeout()。这样您就可以控制异步请求何时返回。它使测试更容易。

  • 将您的 $httpBackend 和控制器拉出到 beforeEach 语句中。创建控制器后,它会触发两个 url。然后你可以单独评估它。当它在it 语句中被隔离时,它不会调用另一个 $http 并抛出意外的 url 错误。

  • 您还应该模拟 $http 请求的响应,而不是 passThrough。您并不总是有互联网连接,响应可能会发生变化。所以让模拟数据看起来像你期望的那样。

  • 此外,$httpBackend.whenGET('httpS://MY_DOMAIN_2.org/projectList') 请求的 URL 不正确。它应该是一个小写的s 和一个.com url。这是因为控制器正在请求

    $http.get('https://MY_DOMAIN_2.com/projectList')

【讨论】:

  • 非常感谢!对于解决方案和明确的解释。关于最后一点,S 大写是一个错字,但为什么应该是 .com 而不是 .org?
  • 顺便说一句,我相信你知道答案:stackoverflow.com/questions/32243100/…
  • 它应该是.com,因为您在控制器中调用了.com$http.get('https://MY_DOMAIN_2.com/projectList').then(function(resp)
【解决方案2】:

不要使用超时,同时测试它们:

it('should load default language list and the default project list', function (){
    $httpBackend.whenGET('http://MY_DOMAIN_1.org/languageList').passThrough();
    $httpBackend.whenGET('httpS://MY_DOMAIN_2.org/projectList').passThrough();

    var TestController = $controller('TestController', { $scope: $scope });

    $httpBackend.flush();

    expect($scope.language_list).not.toEqual([]);
    expect($scope.project_list).not.toEqual([]);
});

【讨论】:

  • 感谢您的回复。我已经尝试过,但我目前收到此错误:没有待处理的刷新请求!
  • 但是按照您的建议联合进行独特的测试是有效的!但只使用超时..为什么刷新不能正常工作?为什么作为一个单独的测试工作而不是作为两个单独的测试工作..?
【解决方案3】:

您需要将 setTimeout 和 done 属性添加到您的刷新中以防止它发生

it('should get data in callback funcion', function (done) {
    $httpBackend.whenGET(/\/my-endpoint/).respond(mockDataResponse);

    apiFactory.getCurrencyFormat('en', function (res, err) {
        expect(res.a).to.deep.equal(generalMock.a);
        expect(res.b).to.deep.equal(generalMock.b);
    });

    setTimeout(function () {
        done();
        $httpBackend.flush();
    }, 200);
});

【讨论】:

    猜你喜欢
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    相关资源
    最近更新 更多