Учитывая метод контроллера, например:
def show
@model = Model.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => model }
end
end
Как лучше всего написать интеграционный тест, который утверждает, что возвращаемый результат имеет ожидаемый XML?





Установите заголовок принятия объектов запроса:
@request.accept = 'text/xml' # or 'application/xml' I forget which
Затем вы можете утверждать, что тело ответа совпадает с тем, что вы ожидали.
assert_equal '<some>xml</some>', @response.body
Этот assert_equal тоже очень хрупкий. Нет никакой гарантии порядка элементов или атрибутов; если он изменится, ваш тест сломается. Сравнение буквальных строк - неправильный способ проверки равенства XML-деревьев.
Это идиоматический способ тестирования ответа 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
Это функциональный тест, который у меня уже есть. Ищу интеграционный тест.
Комбинация использования формата и 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.
Эти 2 ответа великолепны, за исключением того, что мои результаты включают поля datetime, которые в большинстве случаев могут отличаться, поэтому assert_equal не работает. Похоже, что мне нужно будет обработать включение @response.body с помощью анализатора XML, а затем сравнить отдельные поля, количество элементов и т. д. Или есть более простой способ?
Да; поля даты и времени - еще одна причина, по которой assert_equal - неправильный способ сравнения деревьев XML. Что касается меня, я не сравнивал весь объект на равенство в своих тестах; Я использовал assert_select (как показал ntalbott выше) для конкретных атрибутов, которые хочу проверить.
Ответ от 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.)
Я знаю эту часть, ищу интеграционный тест A..Z