如何使用 Angular / Karma / Jasmine 正确测试放置(或 post)请求?
How to test properly a put (or post) request with Angular / Karma / Jasmine?
我正在为 Angular 的应用程序使用网络服务。我做了 "GET" 请求并像这样用 Karma / Jasmine 测试了它:
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');
});
});
效果很好。
所以现在,我想测试 PUT 方法(以及 POST 方法之后)。但是,我没有找到正确的方法。
我最后一次尝试是这样的:
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 = 'pierrre.stan@test.fr';
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');
});
});
但是返回的是旧数据。我花了很多时间寻找正确的测试方法,但我一无所获。
木厂:
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);
}
};
}]);
当您进行测试时,$httpBackend
只是一个简单的模拟。所有真正的功能都关闭了。这个模拟的 $httpBackend
唯一做的就是有方法来验证您的请求。
当您执行以下操作时:
$httpBackend.when('PUT', url).respond(....);
它实际上并没有对任何集合做任何真正的 "PUT"。你只是说:嘿,当 PUT 请求发生时,请用 X 响应。它不会对任何资源进行 PUT,它只是一种知道 PUT 已经完成的方式。
举个例子,不是你应该在测试中做的事情,这是一个模拟的 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];
});
看看我如何用 PUT.
更新 "things" 集合
所以对于您刚才所做的测试,您不需要 PUT 到 return 修改后的数据源 Pierre,您只需要确保已拨打电话,仅此而已。
我建议你从 .when
切换到 .expect
所以如果你期望调用 Customer.put
会执行那个 "PUT" 请求,测试将失败如果它从未被制造出来。
所以这里的问题是,不要忘记在测试中需要做什么,您实际上并不需要更新资源,只是需要访问不同的端点。
我正在为 Angular 的应用程序使用网络服务。我做了 "GET" 请求并像这样用 Karma / Jasmine 测试了它:
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');
});
});
效果很好。 所以现在,我想测试 PUT 方法(以及 POST 方法之后)。但是,我没有找到正确的方法。
我最后一次尝试是这样的:
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 = 'pierrre.stan@test.fr';
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');
});
});
但是返回的是旧数据。我花了很多时间寻找正确的测试方法,但我一无所获。
木厂:
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);
}
};
}]);
当您进行测试时,$httpBackend
只是一个简单的模拟。所有真正的功能都关闭了。这个模拟的 $httpBackend
唯一做的就是有方法来验证您的请求。
当您执行以下操作时:
$httpBackend.when('PUT', url).respond(....);
它实际上并没有对任何集合做任何真正的 "PUT"。你只是说:嘿,当 PUT 请求发生时,请用 X 响应。它不会对任何资源进行 PUT,它只是一种知道 PUT 已经完成的方式。
举个例子,不是你应该在测试中做的事情,这是一个模拟的 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];
});
看看我如何用 PUT.
更新 "things" 集合所以对于您刚才所做的测试,您不需要 PUT 到 return 修改后的数据源 Pierre,您只需要确保已拨打电话,仅此而已。
我建议你从 .when
切换到 .expect
所以如果你期望调用 Customer.put
会执行那个 "PUT" 请求,测试将失败如果它从未被制造出来。
所以这里的问题是,不要忘记在测试中需要做什么,您实际上并不需要更新资源,只是需要访问不同的端点。