2014-10-28 98 views
0

测试服务,我做这个控制器AngularJs:茉莉

app.controller('controller',['$scope','httpServices',function($scope,httpServices){ 
    $scope.items= undefined; 

    httpServices.getItems(function(items){ 
     $scope.items= items; 
    }); 
}]); 

和我写了这个测试

describe('controller', function() { 
     beforeEach(inject(function ($rootScope, $controller) { 
      scope = $rootScope.$new(); 
      controller = $controller('controller', { 
       '$scope': scope 
      }); 
     })); 
     it('defined', function() { 
      expect(scope.items).toBeUndefined(); 
     }) 
    }); 

我如何测试scope.items已经叫售后服务?

+0

任何你没有从'httpServices.getItems'返回承诺的原因? – 2014-10-29 07:54:32

回答

0

我假设你的服务httpServices正在发出一些http请求。因此,您应该使用mock-backend服务来测试您的控制器。

这样的事情,注意,我已经在代码中提出的意见:

describe('Your specs', function() { 
    var $scope, 
     $controller, 
     $httpBackend; 

    // Load the services's module 
    beforeEach(module('yourApp')); 

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

    //THIS LINE IS VERY IMPORTANT, HERE YOU HAVE TO MOCK THE RESPONSE FROM THE BACKEND 
    $httpBackend.when('GET', 'http://WHATEVER.COM/API/SOMETHING/').respond({}); 

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

    describe('Your controller', function() { 
    it('items should be undefined', function() { 
     createController(); 
     expect(scope.items).toBeUndefined(); 
    }); 

    it('items should exist after getting the response from the server', function() { 
     //THIS LINE IS ALSO VERY IMPORTANT, IT EMULATES THE RESPONSE FROM THE SERVER 
     $httpBackend.flush(); 
     expect(scope.items).toBeDefined(); 
    }); 
    }); 
}); 
+0

在第二次测试中,应该期待(scope.items).toBeDefined(); – 2014-10-28 23:44:16

+0

@AbhishekJain当然,我只是改变了它。但为什么?旧的代码是100%等价的:'expect(scope.items).not.toBeUndefined()'与'expect(scope.items).toBeDefined()' – Josep 2014-10-28 23:49:51

+0

相同啊!我的坏!不知道,我道歉! – 2014-10-28 23:51:59

0

问题标题指出这是测试服务,但问题的代码看起来像一个尝试正在测试控制器。这个答案描述了如何测试控制器。为了


如果您正在测试调用httpServices.getItems控制器,那么你需要嘲笑它/存根getItems

  • 控制它的测试
  • 不承担的任何行为真实httpServices.getItems。毕竟,你正在测试控制器,而不是服务。

做到这一点的方法是在beforeEach块(在创建控制器之前调用)提供虚假实施getItems那只是保存传递给它的回调。

var callback; 
beforeEach(inject(function(httpServices) { 
    callback = null; 
    spyOn(httpServices, 'getItems').and.callFake(function(_callback_) { 
    callback = _callback_; 
    }); 
}); 

在测试中,您可以调用此回调函数,传入一些假数据,并测试它是否已在示波器上正确设置。

it('saves the items passed to the callback on the scope', function() { 
    var testItems = {}; 
    callback(testItems); 
    expect($scope.items).toBe(testItems); 
}); 

由此可以看出,在http://plnkr.co/edit/Z7N6pZjCS9ojs9PZFD04?p=preview


工作。如果你想测试httpServices.getItems本身,然后单独测试是那个地方。假设getItems调用$http,那么您很可能需要使用$httpBackend来处理模拟响应。最有可能的是,这些测试不会实例化任何控制器,我怀疑不需要在任何范围上做任何事情。