在我看来,我加载的动画一直显示,直到我收到来自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/
然而,插入该配置方法使我的所有测试失败(我认为因为模板没有及时加载),它会延迟所有响应,所以它不是我真正需要的。
那么如何延迟这一次通话的响应呢?理想情况下,我只想延迟它进行测试。
答案 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);