2008-09-12 5 views

Répondre

11

Combinaison d'utiliser le format et 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 Vérifions assert_select dans les rails docs.

0

Définissez les objets de requête en-tête Accept:

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

Ensuite, vous pouvez affirmer le corps de la réponse est égale à ce que vous attendiez

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

Cette partie, je sais, la recherche d'un test d'intégration A..Z –

+1

That assert_equal est également très fragile. Il n'y a aucune garantie de l'ordre des éléments ou des attributs; Si cela change, votre test va casser. La comparaison de chaîne littérale n'est pas la bonne façon de vérifier l'égalité des arbres XML. – bjnord

5

C'est la façon idiomatiques de tester la réponse XML 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 
+0

C'est un test fonctionnel, que j'ai déjà. Vous cherchez un test d'intégration. –

1

Ces 2 réponses sont excellentes, sauf que mes résultats incluent les champs datetime, qui doivent être différents dans la plupart des cas, donc le assert_equal échoue. Il semble que je vais devoir traiter l'inclusion @response.body en utilisant un analyseur XML, puis comparer les champs individuels, le nombre d'éléments, etc. Ou y at-il un moyen plus facile?

+0

Oui; Les champs de date et d'heure sont une autre raison pour laquelle assert_equal est la mauvaise façon de comparer les arbres XML. Pour ma part, je n'ai pas comparé l'ensemble de l'objet à l'égalité dans mes tests; J'ai utilisé assert_select (comme montré ci-dessus par ntalbott) pour les attributs spécifiques que je veux vérifier. – bjnord

5

La réponse de ntalbott montre une action d'obtention. L'action post est un peu plus compliquée; Si vous souhaitez envoyer le nouvel objet sous forme de message XML et que les attributs XML s'affichent dans le hachage params du contrôleur, vous devez obtenir les en-têtes correctement. 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 de poste ne doit pas être un hachage de paramètres; il peut s'agir d'une chaîne (contenant du XML), si les en-têtes ont raison. Le troisième argument, @headers, est la partie qui m'a pris beaucoup de recherches pour comprendre.

(Notez aussi l'utilisation de to_s lorsque l'on compare une valeur entière dans assert_select.)

Questions connexes