如何用角/业/茉莉花正确地测试put(或post)请求?

时间:2022-08-24 22:30:20

I am using webservices for an app with Angular. I did "GET" requests and tested it with Karma / Jasmine like this :

我正在使用webservices开发一个有棱角的应用。我确实“收到”了请求,然后用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');
    });
});

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.

它的工作原理。现在,我想测试PUT方法(以及POST方法之后)。但是,我没有找到正确的方法。

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 = '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');
        });
    });

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);
        }
    };
}]);

1 个解决方案

#1


2  

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.

在进行测试时,$ http后台只是一个简单的模拟。所有真正的功能都关闭了。这个模拟的$ http后端所做的惟一事情就是拥有验证请求的方法。

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.

它实际上并没有针对任何收藏做任何真正的“投入”。你只是在说:嘿,当一个PUT请求发生时,请用x来回复。它不会对任何资源做一个PUT操作,它只是一种知道PUT已经完成而不是其他任何东西的方法。

As an example and NOT something you should do on tests, here is a mocked 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];
});

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.

因此,对于您刚才所做的测试,您不需要PUT返回经过修改的数据源,只需确保调用已经完成,而不需要其他任何东西。

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.

我建议你从“何时”改为“期待”,如果你对打电话的客户有期望的话。put将执行“put”请求,如果从未执行,测试将失败。

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.

这里的问题是,不要忘记在测试中需要做什么,你不需要更新你的资源,只需要访问不同的端点。

#1


2  

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.

在进行测试时,$ http后台只是一个简单的模拟。所有真正的功能都关闭了。这个模拟的$ http后端所做的惟一事情就是拥有验证请求的方法。

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.

它实际上并没有针对任何收藏做任何真正的“投入”。你只是在说:嘿,当一个PUT请求发生时,请用x来回复。它不会对任何资源做一个PUT操作,它只是一种知道PUT已经完成而不是其他任何东西的方法。

As an example and NOT something you should do on tests, here is a mocked 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];
});

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.

因此,对于您刚才所做的测试,您不需要PUT返回经过修改的数据源,只需确保调用已经完成,而不需要其他任何东西。

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.

我建议你从“何时”改为“期待”,如果你对打电话的客户有期望的话。put将执行“put”请求,如果从未执行,测试将失败。

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.

这里的问题是,不要忘记在测试中需要做什么,你不需要更新你的资源,只需要访问不同的端点。