次のようなコントローラメソッドが与えられます:
def show
@model = Model.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => model }
end
end
リターンに期待されるXMLがあることを主張する統合テストを作成するための最良の方法は何ですか?
次のようなコントローラメソッドが与えられます:
def show
@model = Model.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => model }
end
end
リターンに期待されるXMLがあることを主張する統合テストを作成するための最良の方法は何ですか?
統合テストで format と assert_select を組み合わせて使用すると、うまく機能します。
class ProductsTest < ActionController::IntegrationTest
def test_contents_of_xml
get '/index/1.xml'
assert_select 'product name', /widget/
end
end
詳細については、Rails ドキュメントのassert_selectを確認してください。
これは、コントローラーからの 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
ntalbott からの回答は get アクションを示しています。投稿アクションは少しトリッキーです。新しいオブジェクトを XML メッセージとして送信し、コントローラーの params ハッシュに XML 属性を表示する場合は、ヘッダーを正しく取得する必要があります。以下に例を示します (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
ここで、post の 2 番目の引数がパラメーター ハッシュである必要がないことがわかります。ヘッダーが正しい場合は、文字列 (XML を含む) にすることができます。3 番目の引数である @headers は、理解するために多くの調査を行った部分です。
(assert_select で整数値を比較するときの to_s の使用にも注意してください。)
私の結果には日時フィールドが含まれていることを除いて、これらの2つの答えは素晴らしいです。これはほとんどの状況で異なるため、assert_equal
失敗します。XML パーサーを使用してインクルードを処理し@response.body
、個々のフィールド、要素の数などを比較する必要があるようです。または、もっと簡単な方法はありますか?
リクエスト オブジェクトの Accept ヘッダーを設定します。
@request.accept = 'text/xml' # or 'application/xml' I forget which
次に、応答本文が期待していたものと等しいと断言できます
assert_equal '<some>xml</some>', @response.body