如何通过$ http调用发送模拟响应数据?

时间:2016-09-14 23:44:03

标签: angularjs unit-testing karma-jasmine

我有一个调用服务的控制器并设置一些变量。我想测试那些变量是否设置为响应。

我的控制器:

tankService.getCurrentStats().success(function (response) {
            $scope.stats.tankAvgHours = response.tankAvgHours;
            $scope.stats.stillAvgHours = response.stillAvgHours;
            $scope.stats.stillRemaining = response.stillRemaining;
            $scope.stats.tankRemaining = response.tankRemaining;
            $scope.stats.loaded = true;
    });

我的测试:

...
var STATS_RESPONSE_SUCCESS =
            {
                tankAvgHours:8,
                stillAvgHours:2,
                stillRemaining: 200,
                tankRemaining:50
            };
...

spyOn(tankService, "getCurrentStats").and.callThrough();

...

it('calls service and allocates stats with returned data', function () {

            expect($scope.stats.loaded).toBeFalsy();

            $httpBackend.whenPOST('../services/tanks/RelayTankService.asmx/getCurrentStats').respond(200, $q.when(STATS_RESPONSE_SUCCESS));

            tankService.getCurrentStats()
                .then(function(res){
                    result = res.data.$$state.value;
                });

            $httpBackend.flush();


            expect($scope.stats.tankAvgHours).toEqual(result.tankAvgHours);
            expect($scope.stats.stillAvgHours).toEqual(result.stillAvgHours);
            expect($scope.stats.stillRemaining).toEqual(result.stillRemaining);
            expect($scope.stats.tankRemaining).toEqual(result.tankRemaining);
            expect($scope.stats.loaded).toBeTruthy();

        });

结果是我的范围变量未定义且不等于我的模拟响应数据。是否可以传递模拟值,以便我可以正确地测试成功函数填充变量?

谢谢!

2 个答案:

答案 0 :(得分:1)

我认为你正在测试错误的东西。服务应该只负责返回数据。如果要测试服务,那么一定要模拟httpbackend并调用服务,然后验证服务返回的数据,而不是$ scope。如果要测试控制器是否调用服务并将数据添加到作用域,则需要在测试中创建控制器,为其创建作用域,然后测试是否添加了这些变量。我没有对此进行测试,因此语法可能会关闭,但这可能是您想要进入的方向。

var scope, $httpBackend, controller;
  beforeEach(inject(function(_$httpBackend_, $controller, $rootScope) {
    $httpBackend = _$httpBackend_;
   $httpBackend.whenPOST('../services/tanks/RelayTankService.asmx/getCurrentStats').respond(200, $q.when(STATS_RESPONSE_SUCCESS));
    scope = $rootScope.$new();
     controller = $controller('myController', {
      $scope: scope
    });


  }));
it('calls service and allocates stats with returned data', function () {

            expect(scope.stats.loaded).toBeFalsy();
            $httpBackend.flush();
            expect(scope.stats.tankAvgHours).toEqual(result.tankAvgHours);
            expect(scope.stats.stillAvgHours).toEqual(result.stillAvgHours);
            expect(scope.stats.stillRemaining).toEqual(result.stillRemaining);
            expect(scope.stats.tankRemaining).toEqual(result.tankRemaining);
            expect(scope.stats.loaded).toBeTruthy();

        });

答案 1 :(得分:1)

由于您正在测试控制器,因此无需像在测试中那样模仿$http POST

您只需要模仿tankService的{​​{1}}方法。

假设您的getCurrentStats tankService方法返回一个承诺,这就是您的测试必须如何:

getCurrentStats

希望这有帮助。