使用$ httpBackend延迟响应

时间:2014-08-18 17:18:37

标签: angularjs mocking protractor httpbackend

在我看来,我加载的动画一直显示,直到我收到来自API的回复。

//Displayed before we've received API response
<p ng-if="vm.vehicles == null">Loading ...</p>

//Displayed once we received response for the API
<table ng-if="vm.vehicles">
    <tr ng-repeat="vehicle.vm.vehicles">...</tr>

要进行测试,我使用$httpBackend Angular模块。像这样:

$httpBackend.whenGET('api/vehicles').respond({vehicles: [...]});

问题

我想编写一个测试来检查加载动画是否显示。

我试过了:

expect(ptor.isElementPresent(By.cssContainingText('p', 'Loading'))).to.eventually.be.true;`

但我没有通过。所以我认为我需要有条件地延迟我从$ httpBackend得到的响应。

我发现了这篇博文http://endlessindirection.wordpress.com/2013/05/18/angularjs-delay-response-from-httpbackend/

然而,插入该配置方法使我的所有测试失败(我认为因为模板没有及时加载),它会延迟所有响应,所以它不是我真正需要的。

那么如何延迟这一次通话的响应呢?理想情况下,我只想延迟它进行测试。

2 个答案:

答案 0 :(得分:0)

查看$http的文档,特别是interceptors

这是有趣的一点:

  

response:使用http响应对象调用拦截器。该函数可以自由修改响应对象或创建新对象。该函数需要直接返回响应对象,或者作为包含响应或新响应对象的promise

换句话说,您可以拦截响应而不是立即返回响应,返回一个在超时后返回响应的承诺......

e.g。 plunkr example

但是在端到端测试的情况下,您必须处理$httpBackend对象。

这一点起作用:

  

与单元测试相反,在端到端测试场景中或在使用模拟替换真实后端api开发应用程序的情况下,通常希望某些类别的请求绕过模拟并发出真实的http请求(例如,从Web服务器获取模板或静态文件)。要使用此行为配置后端,请使用passThrough请求处理程序而不是响应。

翻译:你可以使用.passThrough(),你的拦截器应该可以工作:

$httpBackend.whenGET('api/vehicles').passThrough();

缺点是这可以满足实际要求。

你也可以查看这个非常相似的问题: AngularJS - Using ngMockE2E $httpBackend how can I delay a specific response?

答案 1 :(得分:0)

我能够通过使用超时解析$ httpBackend的respond()方法中可用函数内的promise来实现此功能。

我正在测试我的一个角度服务上的方法,该方法使用API​​调用的结果填充列表。另外,我对该服务进行了bool,指示列表何时加载以及何时完成。因此,在我的特定单元测试中,我只想确保将“loading”bool设置为true,然后在完成时返回false(并且在成功填充该列表时将“finished loaded”bool设置为true。

要做到这一点,我需要延迟我的模拟httpBackend GET响应,允许我检查“loading”bool设置为true并且“完成加载”bool未定义,但是在超时过去之后需要两个bool拥有新的价值观。

更新:抱歉没有及早更新。我之前在response()中放了$ timeout,但是因为我没有执行$ timeout.flush()$ timeout函数内的expect语句没有执行。我不再模拟这种延迟了,但我忘了我已经发布了这里。感谢@ Mark-Amery引起我的注意。

var fakeList = [{ id: 1, name: "item 1" }, { id: 2, name: "item 2" }];

$http.expectGET('/myapi/myresource').respond(fakeList);

 myAngularService.myMethod();

 expect(myAngularService.listIsLoading).toBeTruthy();
 expect(myAngularService.listFinishedSuccessfully).toBeUndefined();

 $http.flush();

 expect(myAngularService.listIsLoading).toBeFalsy();
 expect(myAngularService.listFinishedSuccessfully).toBeTruthy();
 expect(myAngularService.myList).toEqual(fakeList);