Reputation: 578
I am using webservices for an app with Angular. I did "GET" requests and tested it with Karma / Jasmine like this :
beforeEach(module('webservices'));
beforeEach(inject(function(_$httpBackend_) {
$httpBackend = _$httpBackend_;
jasmine.getJSONFixtures().fixturesPath='base/tests/json/api';
// Customers
$httpBackend.when('GET', 'http://prestashop/api/customers/1?ws_key=key&output_format=JSON')
.respond(getJSONFixture('customers/1.json'));
$httpBackend.when('GET', 'http://prestashop/api/customers/2?ws_key=key&output_format=JSON')
.respond(getJSONFixture('customers/2.json'));
$httpBackend.when('PUT', 'http://prestashop/api/customers/1?ws_key=key&output_format=JSON')
.respond(getJSONFixture('customers/1.json'));
}));
it("\n\ngets firstname about customer 1", function(){
angular.mock.inject(function (Customer) {
var client;
Customer.get(1).success(function(data, status, headers, config){
client = data;
}). error(function(data, status, headers, config) { });
$httpBackend.flush();
expect(client.customer.firstname).toBe('John');
});
});
It works perfectly. So now, I want to test a PUT method (and after a POST method). But, I didn't find the right way to do this.
My last try was this :
it("\n\nputs a different firstname, lastname, email, passwd about customer 1", function(){
angular.mock.inject(function (Customer) {
var idCustomer = 3;
var firstname = 'Pierre',
lastname = 'Stan',
passwd = 'mdp',
email = '[email protected]';
var client = {customer: {id: idCustomer,
firstname: firstname,
passwd: passwd,
lastname: lastname,
email: email
}
};
var clientReturn;
Customer.put(idCustomer, client).success(function(data, status, headers, config){
clientReturn = data;
}). error(function(data, status, headers, config) { });
$httpBackend.flush();
expect(clientReturn .customer.fistname).toBe('Pierre');
});
});
But it is returned the old data. I spent a lot of time to find a right way to test, but I found nothing.
Mu factory :
var webservices = angular
.module('webservices', []);
webservices.factory('Customer', ['$http', function($http){
var baseDir = "http://prestashop/api";
var customerDir = "/customers";
var keyDir = "?ws_key=key";
var formatDir = "&output_format=JSON";
return {
get: function(id) {
var urlDir = baseDir + customerDir + "/" + id + keyDir + formatDir;
return $http.get(urlDir);
},
put: function(id, data) {
var urlDir = baseDir + customerDir + "/" + id + keyDir + formatDir;
return $http.put(urlDir, data);
},
post: function(data) {
var urlDir = baseDir + customerDir + keyDir + formatDir;
return $http.post(urlDir, data);
}
};
}]);
Upvotes: 3
Views: 6868
Reputation: 12018
When you're on tests, $httpBackend
is just a simple mock. All the real functionality is off. The only thing that this mocked $httpBackend
does is just have methods to verify your requests.
When you do a:
$httpBackend.when('PUT', url).respond(....);
It is not really doing any real "PUT" against any collection. You're just saying: Hey, when a PUT petition occurs, please respond with X. It is not going to do a PUT to any resource, it is just a way to know that the PUT has been made and nothing else.
As an example and NOT something you should do on tests, here is a mocked PUT:
$httpBackend.whenPUT(/^\/api\/todos\/\d+$/).respond(function(method, url, data, headers) {
var item = JSON.parse(data);
for (var i = 0, l = things.length; i < l; i++) {
if (things[i].id === item.id) {
things[i] = item;
break;
}
}
return [200, item];
});
See how I update a "things" collection with what I PUT.
So for tests as you just did, you don't need the PUT to return a modified data source with Pierre, you just need to make sure that the call has been made and nothing else.
I recommend you to switch from .when
to .expect
so if you put an expectation that calling Customer.put
will do that "PUT" request, the test will fail if it is never made.
So the thing here is, don't forget what you need to do in a test, you don't really need your resource being updated, just that the different endpoints are hit.
Upvotes: 3