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 ?

Était-ce utile?

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top