2012-01-25 1 views
0

В настоящее время я использую рельсы 3.1.3, cucumber-rails 1.2.1, rspec-rails 2.8.1 и json_spec 0.8.0. Я создаю успокаивающий API веб-сервисов, который будет использоваться приложением Android. Я использую методы TDD/BDD и смог успешно протестировать действия веб-сервисов с помощью get() и post() в моих определениях в Cucumber. Однако при использовании put() у меня возникла проблема.Rack :: Test PUT метод с JSON не может преобразовать JSON в params

Вот мой device_update.feature:

Feature: Updating a Device 
    The web service should accept a PUT request to update device settings. 

    Scenario: The device information is updated when valid data is posted to the web service. 
    Given a device exists 
    When I put "/services/devices/4A3CABD4C4DE6E9F.json" with: 
     """ 
     { 
     "device": { 
      "carrier": "SPRINT" 
     } 
     } 
     """  
    Then the JSON should be: 
     """ 
     { 
     "message": "Device updated.", 
     "response_code": 1 
     } 
     """ 

Мое определение шаг:

When /^I get "([^"]*)"$/ do |path| 
    get(path) 
end 

When /^I post to "([^"]*)" with:$/ do |path, json_string| 
    post(path, json_string, {"CONTENT_TYPE" => "application/json"}) 
end 

When /^I put "([^"]*)" with:$/ do |path, json_string| 
    put(path, json_string, {"CONTENT_TYPE" => "application/json"}) 
end 

При выполнении теста, я получаю следующее:

When I put "/services/devices/4A3CABD4C4DE6E9F.json" with: 
    """ 
    { 
    "device": { 
     "carrier": "SPRINT" 
    } 
    } 
    """ 
    You have a nil object when you didn't expect it! 
    You might have expected an instance of Array. 
    The error occurred while evaluating nil.[] (NoMethodError) 
    ./app/controllers/services/devices_controller.rb:75:in `update' 
    ./features/step_definitions/request_steps.rb:10:in `/^I put "([^"]*)" with:$/' 
    features/services/devices/device_update.feature:7:in `When I put "/services/devices/4A3CABD4C4DE6E9F.json" with:' 
Then the JSON should be: 
    """ 
    { 
    "message": "Device updated.", 
    "response_code": 1 
    } 
    """ 

Когда я посмотрите на журнал, я вижу следующее:

Started PUT "/services/devices/4A3CABD4C4DE6E98.json" for 127.0.0.1 at 2012-01-25 11:36:16 -0800 
Processing by Services::DevicesController#update as JSON 
Parameters: {"{\n \"device\": {\n \"carrier\": "SPRINT"\n }\n}"=>nil, "id"=>"4A3CABD4C4DE6E98"} 

Я урезал активные вызовы записи, поскольку они не имеют отношения к делу. Очевидно, что JSON не преобразуется в правильные параметры, и именно поэтому я получаю неожиданный ноль.

Любые мысли о том, как сделать эту работу?

ответ

1

Вы не должны передавать строку до put. Он заботится о преобразовании в строку JSON, что обычно хорошо. Что здесь происходит, так это то, что ваша строка JSON: JSONified еще раз put.

Вы должны разобрать строку JSON первого и передать полученный объект put:

When /^I put "([^"]*)" with:$/ do |path, json_string| 
    payload = JSON.parse(json_string) 
    put(path, payload, {"CONTENT_TYPE" => "application/json"}) 
end 

также тип содержимого, вероятно, нет необходимости.

+0

Мне любопытно, почему мне нужно будет использовать этот подход с помощью put(), когда post() отлично работает следующим образом: 'Когда/^ я отправляю в" ([^ "] *)" с: $/do | path, json_string | post (путь, json_string, {"CONTENT_TYPE" => "application/json"}) end' Два метода в стойке, похоже, делают то же самое, но JSON Автоматически анализируется в post(), но не put()? – Dave

+0

Это не совсем понятно для меня, но я думаю, что это связано с тем, как Rack обрабатывает запрос и его содержимое. – jbpros

+0

Это работает для вас? – jbpros