Testing rendering of a given layout with RSpec & Rails

后端 未结 11 1385
滥情空心
滥情空心 2020-12-24 12:31

Is it possible to test the use of a given layout using RSpec with Rails, for example I\'d like a matcher that does the following:

response.should use_layout(         


        
相关标签:
11条回答
  • 2020-12-24 13:06

    There's already a perfectly functional matcher for this:

    response.should render_template(:layout => 'fooo')
    

    (Rspec 2.6.4)

    0 讨论(0)
  • 2020-12-24 13:07

    I had to write the following to make this work:

    response.should render_template("layouts/some_folder/some_layout", "template-name")
    
    0 讨论(0)
  • 2020-12-24 13:11

    Here's the solution I ended up going with. Its for rpsec 2 and rails 3.
    I just added this file in the spec/support directory. The link is: https://gist.github.com/971342

    # spec/support/matchers/render_layout.rb

    ActionView::Base.class_eval do unless instance_methods.include?('_render_layout_with_tracking') def _render_layout_with_tracking(layout, locals, &block) controller.instance_variable_set(:@_rendered_layout, layout) _render_layout_without_tracking(layout, locals, &block) end alias_method_chain :_render_layout, :tracking end end

    # You can use this matcher anywhere that you have access to the controller instance, # like in controller or integration specs. # # == Example Usage # # Expects no layout to be rendered: # controller.should_not render_layout # Expects any layout to be rendered: # controller.should render_layout # Expects app/views/layouts/application.html.erb to be rendered: # controller.should render_layout('application') # Expects app/views/layouts/application.html.erb not to be rendered: # controller.should_not render_layout('application') # Expects app/views/layouts/mobile/application.html.erb to be rendered: # controller.should_not render_layout('mobile/application') RSpec::Matchers.define :render_layout do |*args| expected = args.first match do |c| actual = get_layout(c) if expected.nil? !actual.nil? # actual must be nil for the test to pass. Usage: should_not render_layout elsif actual actual == expected.to_s else false end end

    failure_message_for_should do |c| actual = get_layout(c) if actual.nil? && expected.nil? "expected a layout to be rendered but none was" elsif actual.nil? "expected layout #{expected.inspect} but no layout was rendered" else "expected layout #{expected.inspect} but #{actual.inspect} was rendered" end end

    failure_message_for_should_not do |c| actual = get_layout(c) if expected.nil? "expected no layout but #{actual.inspect} was rendered" else "expected #{expected.inspect} not to be rendered but it was" end end

    def get_layout(controller) if template = controller.instance_variable_get(:@_rendered_layout) template.virtual_path.sub(/layouts\//, '') end end end

    0 讨论(0)
  • 2020-12-24 13:11

    controller.active_layout.name works for me.

    0 讨论(0)
  • 2020-12-24 13:17

    response.should render_template("layouts/some_folder/some_layout") response.should render_template("template-name")

    0 讨论(0)
提交回复
热议问题