In my view I have loading animation that is displayed until I receive a response from the 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>
To do my testing, I use the $httpBackend
Angular module. Something like this:
$httpBackend.whenGET('api/vehicles').respond({vehicles: [...]});
Problem
I want to write a test to check the the loading animation is displayed.
I tried:
expect(ptor.isElementPresent(By.cssContainingText('p', 'Loading'))).to.eventually.be.true;`
but i does't pass. So i think I need to conditionally delay the response I get from $httpBackend.
I found this blog post http://endlessindirection.wordpress.com/2013/05/18/angularjs-delay-response-from-httpbackend/
However, inserting that config method made all my tests fails (I think because the templates aren't loaded in time), it delays ALL responses so it's not really what I need.
So how can I delay the response for that one call? Ideally, I would like to delay it only for that test.
Look at the documentation of
$http
, in particularinterceptors
.This is the interesting bit:
In other words, you could intercept the response and rather than return it right away, return a promise that would return the response after a timeout...
e.g. plunkr example.
But in the case of end-to-end testing, you have to deal with an
$httpBackend
object.This bit comes into play:
Translation: you could use
.passThrough()
and your interceptors should work:The drawback is that this would do the actual request.
You can also check this question which is very similar: AngularJS - Using ngMockE2E $httpBackend how can I delay a specific response?
I was able to get this to work by using a timeout to resolve a promise inside the function available on the respond() method of $httpBackend.
I was testing a method on an angular service of mine that populates a list with the results from an API call. Additionally, I have bools on that service that indicate when the list is loading and when it is finished. So in my particular unit test I wanted simply to make sure the "loading" bool was set to true and then back to false when finished (and that the "finished loading" bool was set to true upon successful filling of that list.
To do this, I needed to delay my mocked httpBackend GET response, allowing me to check that the "loading" bool was set to true and the "finished loading" bool was undefined, but then after the timeout elapsed both bools needed to have new values.
UPDATE: Apologies for not updating this sooner. I was putting a $timeout inside the respond() before, however because I wasn't performing a $timeout.flush() the expect statements inside the $timeout function were not executing. I don't simulate delays that way anymore, but I forgot I had this posted here. Thanks @Mark-Amery for bringing to my attention.