Come impostare un test di integrazione Rails per i metodi XML?
-
09-06-2019 - |
Domanda
Dato un metodo di controllo come:
def show
@model = Model.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => model }
end
end
Qual è il modo migliore per scrivere un test di integrazione che affermi che il ritorno ha l'XML previsto?
Soluzione
Una combinazione dell'utilizzo del formato e assert_select in un test di integrazione funziona alla grande:
class ProductsTest < ActionController::IntegrationTest
def test_contents_of_xml
get '/index/1.xml'
assert_select 'product name', /widget/
end
end
Per maggiori dettagli controlla assert_select nei documenti Rails.
Altri suggerimenti
La risposta di ntalbott mostra un'azione get.L'azione post è un po' più complicata;se vuoi inviare il nuovo oggetto come messaggio XML e visualizzare gli attributi XML nell'hash params nel controller, devi ottenere le intestazioni corrette.Ecco un esempio (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
Puoi vedere qui che il secondo argomento da pubblicare non deve essere un hash dei parametri;può essere una stringa (contenente XML), Se le intestazioni sono giuste.Il terzo argomento, @headers, è la parte che mi ha richiesto molte ricerche per capirlo.
(Notare anche l'uso di to_s quando si confronta un valore intero in assert_select.)
Questo è il modo idiomatico di testare la risposta xml da un controller.
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
Queste 2 risposte sono fantastiche, tranne per il fatto che i miei risultati includono i campi data e ora, che saranno diversi nella maggior parte dei casi, quindi il assert_equal
non riesce.Sembra che dovrò elaborare l'inclusione @response.body
utilizzando un parser XML, quindi confrontare i singoli campi, il numero di elementi, ecc.O c'è un modo più semplice?
Imposta l'intestazione di accettazione degli oggetti richiesta:
@request.accept = 'text/xml' # or 'application/xml' I forget which
Quindi puoi affermare che il corpo della risposta è uguale a quello che ti aspettavi
assert_equal '<some>xml</some>', @response.body