Как настроить интеграционный тест Rails для методов XML? - PullRequest
12 голосов
/ 12 сентября 2008

Учитывая метод контроллера как:

def show
  @model = Model.find(params[:id])

  respond_to do |format|
    format.html # show.html.erb
    format.xml  { render :xml => model }
  end
end

Какой лучший способ написать интеграционный тест, который утверждает, что возвращаемый результат имеет ожидаемый XML?

Ответы [ 5 ]

12 голосов
/ 13 сентября 2008

Комбинация использования формата и assert_select в интеграционном тесте прекрасно работает:

class ProductsTest < ActionController::IntegrationTest
  def test_contents_of_xml
    get '/index/1.xml'
    assert_select 'product name', /widget/
  end
end

Для более подробной информации посмотрите assert_select в документации по Rails.

5 голосов
/ 20 августа 2010

Ответ от ntalbott показывает действие get. Пост действий немного сложнее; если вы хотите отправить новый объект в виде сообщения XML, и чтобы атрибуты XML отображались в хэше params в контроллере, вы должны правильно определить заголовки. Вот пример (Rails 2.3.x):

class TruckTest < ActionController::IntegrationTest
  def test_new_truck
    paint_color = 'blue'
    fuzzy_dice_count = 2
    truck = Truck.new({:paint_color => paint_color, :fuzzy_dice_count => fuzzy_dice_count})
    @headers ||= {}
    @headers['HTTP_ACCEPT'] = @headers['CONTENT_TYPE'] = 'application/xml'
    post '/trucks.xml', truck.to_xml, @headers
    #puts @response.body
    assert_select 'truck>paint_color', paint_color
    assert_select 'truck>fuzzy_dice_count', fuzzy_dice_count.to_s
  end
end

Здесь вы можете видеть, что второй аргумент для отправки не обязательно должен быть хешем параметров; это может быть строка (содержащая XML), , если , заголовки правильные. Третий аргумент, @headers, - это та часть, которая потребовала много исследований, чтобы понять.

(Обратите внимание также на использование to_s при сравнении целочисленного значения в assert_select.)

5 голосов
/ 13 сентября 2008

Это идиоматический способ проверки ответа xml от контроллера.

class ProductsControllerTest < ActionController::TestCase
  def test_should_get_index_formatted_for_xml
    @request.env['HTTP_ACCEPT'] = 'application/xml'
    get :index
    assert_response :success
  end
end
1 голос
/ 05 марта 2009

Эти 2 ответа великолепны, за исключением того, что мои результаты включают поля даты и времени, которые в большинстве случаев отличаются друг от друга, поэтому assert_equal не удается. Похоже, мне нужно будет обработать include @response.body с использованием анализатора XML, а затем сравнить отдельные поля, количество элементов и т. Д. Или есть более простой способ?

0 голосов
/ 12 сентября 2008

Установить объекты запроса, принимающие заголовок:

@request.accept = 'text/xml' # or 'application/xml' I forget which

Тогда вы можете утверждать, что тело ответа равно тому, что вы ожидали

assert_equal '<some>xml</some>', @response.body
...