【问题标题】:$http call in after another $http call returned unit test在另一个 $http 调用返回单元测试后调用 $http
【发布时间】:2017-01-09 08:28:44
【问题描述】:

我有一段如下代码

function init() {
        $http({
            method: 'GET',
            url: baseUrl + 'service/'+'/serviceA',
            headers: {
                'Content-Type': "application/json",
            }
        }).then(function successResponse(response) {
            $scope.result = response.data;
            if ($scope.result) {
                // initB is another $http get method
                initB();
            }
          // initC is another $http get method
            initC();
          // initD is another $http get method
            initD();
        });
    }

我的单元测试如下

describe('Controller: toolbarCtrl', function() {
beforeEach(module('TestApp'));

var $httpBackend, $rootScope, createController,$location;

beforeEach(inject(function($injector) {
    $httpBackend = $injector.get('$httpBackend');
    $rootScope = $injector.get('$rootScope');
    $location = $injector.get('$location');
    var $controller = $injector.get('$controller');

    createController = function() {
        return $controller('toolbarCtrl', {
            '$scope': $rootScope
        });
    };       
}));

afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
});

it("init B", function() {    
        $httpBackend.whenGET(/http:\/\/.*\/serviceA.*/).respond(200, true);
        $httpBackend.whenGET(/http:\/\/.*\/serviceB.*/).respond(200, ["A","B","C"]);
        var controller = createController();
        $httpBackend.flush();
        expect($rootScope.B).toBe(["A", "B", "C"]);
    });

但是不行,会抛出异常

不满足的请求:GET /http://./serviceB./

如果我删除此行$httpBackend.whenGET(/http:\/\/.*\/serviceB.*/).respond(200, ["A","B","C"]);

代码不会抛出任何异常,但是B没有被初始化;

如果我删除$httpBackend.whenGET(/http:\/\/.*\/serviceA.*/).respond(200, true);

它会抛出异常:

意外请求:GET http://localhost:8633/serviceA

有人可以帮忙吗?

【问题讨论】:

  • 你意识到你没有在 initB/initC 或 initD 上“等待”
  • @JaromandaX 是的,initB/C/D 可以并行执行,它们没有任何关系,当 init 过程完成后,我将响应数据分配给 B,C,D 变量成功事件处理程序。
  • @Allen4Tech 为什么要测试 $http 方法?它已经被 AngularJS 社区测试过了。您必须创建一个模拟来测试该服务,而模拟意味着没有真正的测试用例。如果它包含任何逻辑,则为该函数提供一个测试用例。我相信我们可以在没有模拟的情况下编写好的和有意义的测试用例。我还为 $http 和其他一些服务编写了带有 mock 的测试用例,但现在我确信我会在编写任何单元测试用例之前进行推理。
  • @Ajay 我不想测试 $http,所以我使用 $httpBackend 来模拟响应。在测试用例中,如果我调用该服务,返回一个数组,真正的代码逻辑会将响应分配给 B,所以我需要测试 B 是否等于我模拟的响应
  • @Allen4Tech 我们可以从 $http 请求中单独测试该逻辑吗?如果可以,那么我们已经测试了该代码,我认为没有必要模拟 $httpBackend。

标签: javascript angularjs unit-testing jasmine


【解决方案1】:

我看不到你的测试中“it”函数之前的代码是什么样的,但看起来你没有实例化 $httpBackend (或者可能在你实例化你的服务/控制器)。您的测试需要在您尝试测试的组件之前调用 $httpBackend

【讨论】:

  • 能否请您仍然包含整个测试代码?至少您声称的部分是在您的服务/控制器之前加载 $httpBackend
  • 嗯,看起来不错,但它失败了很奇怪......你能否也添加你的整个 toolbarCtrl 控制器?也许问题就在那里。
猜你喜欢
  • 2019-10-23
  • 1970-01-01
  • 2021-05-18
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-21
  • 1970-01-01
相关资源
最近更新 更多