12

给定一个控制器方法,如:

def show
  @model = Model.find(params[:id])

  respond_to do |format|
    format.html # show.html.erb
    format.xml  { render :xml => model }
  end
end

编写断言返回具有预期 XML 的集成测试的最佳方法是什么?

4

5 回答 5

12

在集成测试中结合使用 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

于 2008-09-13T15:43:54.037 回答
5

这是测试来自控制器的 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
于 2008-09-13T02:08:04.810 回答
5

ntalbott 的回答显示了一个 get 操作。发布动作有点棘手;如果您想将新对象作为 XML 消息发送,并让 XML 属性显示在控制器的 params 散列中,则必须正确设置标题。这是一个示例(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 的第二个参数不必是参数哈希;如果标题正确,它可以是一个字符串(包含 XML) 。第三个论点,@headers,是我经过大量研究才弄清楚的部分。

(还要注意在 assert_select 中比较整数值时使用 to_s。)

于 2010-08-20T15:10:00.973 回答
1

这两个答案很好,除了我的结果包括日期时间字段,在大多数情况下这些字段是不同的,所以assert_equal失败了。看来我需要@response.body使用 XML 解析器处理包含,然后比较各个字段、元素数量等。或者有更简单的方法吗?

于 2009-03-05T01:47:12.373 回答
0

设置请求对象接受头:

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

然后您可以断言响应正文等于您的预期

assert_equal '<some>xml</some>', @response.body
于 2008-09-12T18:32:02.393 回答