AngularJS入门教程之XHR和依赖注入详解(2)

describe('PhoneCat controllers', function() { describe('PhoneListCtrl', function(){ var scope, ctrl, $httpBackend; beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) { $httpBackend = _$httpBackend_; $httpBackend.expectGET('phones/phones.json'). respond([{name: 'Nexus S'}, {name: 'Motorola DROID'}]); scope = $rootScope.$new(); ctrl = $controller(PhoneListCtrl, {$scope: scope}); }));

注意:因为我们在测试环境中加载了Jasmine和angular-mock.js,我们有了两个辅助方法,module和inject,来帮助我们获得和配置注入器。

用如下方法,我们在测试环境中创建一个控制器:

我们使用inject方法将$rootScope,$controller和$httpBackend服务实例注入到Jasmine的beforeEach函数里。这些实例都来自一个注入器,但是这个注入器在每一个测试内部都会被重新创建。这样保证了每一个测试都从一个周知的起始点开始,并且每一个测试都和其他测试相互独立。

调用$rootScope.$new()来为我们的控制器创建一个新的作用域。

PhoneListCtrl函数和刚创建的作用域作为参数,传递给已注入的$controller函数。

由于我们现在的代码在创建PhoneListCtrl子作用域之前,于控制器中使用$http服务获取了手机列表数据,我们需要告诉测试套件等待一个从控制器来的请求。我们可以这样做:

将请求服务$httpBackend注入到我们的beforeEach函数中。这是这个服务的一个伪版本,这样做在产品环境中有助于处理所有的XHR和JSONP请求。服务的伪版本允许你不用考虑原生API和全局状态——随便一个都能构成测试的噩梦——就可以写测试。

使用$httpBackend.expectGET方法来告诉$httpBackend服务来等待一个HTTP请求,并且告诉它如何对其进行响应。注意到,当我们调用$httpBackend.flush方法之前,响应是不会被发出的。

现在,

it('should create "phones" model with 2 phones fetched from xhr', function() { expect(scope.phones).toBeUndefined(); $httpBackend.flush(); expect(scope.phones).toEqual([{name: 'Nexus S'}, {name: 'Motorola DROID'}]); });

在浏览器里,我们调用$httpBackend.flush()来清空(flush)请求队列。这样会使得$http服务返回的promise(什么是promise请参见这里)能够被解释成规范的应答。

我们设置一些断言,来验证手机数据模型已经在作用域里了。

最终,我们验证orderProp的默认值被正确设置:

it('should set the default value of orderProp model', function() { expect(scope.orderProp).toBe('age'); }); ;

练习

在index.html末尾添加一个{{phones | json}}绑定,观察json格式的手机列表。

在PhoneListCtrl控制器中,把HTTP应答预处理一下,使得只显示手机列表的前五个。在$http回调函数里面使用如下代码:

 $scope.phones = data.splice(0, 5);

总结

现在你应该感觉得到使用AngularJS的服务是多么的容易(这都要归功于AngularJS服务的依赖注入机制),转到步骤6,你会为手机添加缩略图和链接。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzfpff.html