Comment configurer un test d'intégration Rails pour les méthodes XML ?
-
09-06-2019 - |
Question
Étant donné une méthode de contrôleur telle que :
def show
@model = Model.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => model }
end
end
Quelle est la meilleure façon d'écrire un test d'intégration qui affirme que le retour contient le XML attendu ?
La solution
Une combinaison de l'utilisation du format et de assert_select dans un test d'intégration fonctionne très bien :
class ProductsTest < ActionController::IntegrationTest
def test_contents_of_xml
get '/index/1.xml'
assert_select 'product name', /widget/
end
end
Pour plus de détails, consultez assert_select dans la documentation Rails.
Autres conseils
La réponse de ntalbott montre une action get.L'action postérieure est un peu plus délicate ;si vous souhaitez envoyer le nouvel objet sous forme de message XML et que les attributs XML apparaissent dans le hachage des paramètres du contrôleur, vous devez obtenir les bons en-têtes.Voici un exemple (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
Vous pouvez voir ici que le 2ème argument à publier ne doit pas nécessairement être un hachage de paramètres ;il peut s'agir d'une chaîne (contenant du XML), si les en-têtes sont corrects.Le 3ème argument, @headers, est la partie qui m'a demandé beaucoup de recherches pour la comprendre.
(Notez également l'utilisation de to_s lors de la comparaison d'une valeur entière dans assert_select.)
C'est la manière idiomatique de tester la réponse XML d'un contrôleur.
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
Ces 2 réponses sont excellentes, sauf que mes résultats incluent les champs datetime, qui seront différents dans la plupart des circonstances, donc le assert_equal
échoue.Il semble que je devrai traiter l'inclusion @response.body
à l'aide d'un analyseur XML, puis comparez les champs individuels, le nombre d'éléments, etc.Ou existe-t-il un moyen plus simple ?
Définissez l'en-tête d'acceptation des objets de requête :
@request.accept = 'text/xml' # or 'application/xml' I forget which
Ensuite, vous pouvez affirmer que le corps de la réponse est égal à ce que vous attendiez
assert_equal '<some>xml</some>', @response.body