ruby-on-railsxmlrspecxml-builder

Testing XmlBuilder with Rspec


I posted a question (Rails XML builder not rendering) regarding rendering XML using XmlBuilder. That particular issue was resolved but I’ve run into another issue testing this controller action.

The issue seems to be with Rspec as because the same test written in Minitest works fine and using cURL works too.

While debugging this, Rspec never tries to render the xml builder template. It just skips over the template and renders a http status 200 with a blank body.

Here are the controller, xml builder, tests, and test results:

controllers/bars_controller.rb

require 'builder'

class BarsController < ApplicationController

  def show
    @bar = Bar.find(params[:id])
    render template: 'bars/show.xml.builder', formats: [:xml]
  end

 end

/views/bars/show.xml.builder

xml.instruct!
xml.bar do
  xml.foo(@bar.foo)
  xml.bar(@bar.bar)
end

/test/controllers/bars_controller_test.rb

 require 'test_helper'

 class BarsControllerTest < ActionController::TestCase
  setup do
    @bar = Bar.create(foo: 'bar', bar: 'foo')
  end

  test "should show bar" do
    get :show, id: @bar
    assert_response :success
    assert_match "<bar>", response.body
  end
 end

/spec/controllers/bars_controller_spec.rb

 require_relative '../rails_helper'

 describe BarsController do

  describe 'a POST to :show' do
    before do
      @bar = Bar.create(foo: 'bar', bar: 'foo')
      post :show, id: @bar
    end

    it 'should show bar' do
      expect(response).to be_success
      expect(response.body).to include("<bar>")
    end
  end
 end

Test results

> rake test
Run options: --seed 50688

# Running:
.
Finished in 0.096901s, 10.3198 runs/s, 30.9593 assertions/s.
1 runs, 3 assertions, 0 failures, 0 errors, 0 skips

> rspec spec/controllers/bars_controller_spec.rb 
F

Failures:

  1) BarsController a POST to :show responds with xml bar
     Failure/Error: expect(response.body).to include("<bar>")
       expected "" to include "<bar>"
     # ./spec/controllers/bars_controller_spec.rb:13:in `block (3 levels) in <top (required)>'

Finished in 0.01726 seconds (files took 1.53 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/controllers/bars_controller_spec.rb:11 # BarsController a POST to :show responds with xml bar

Solution

  • RSpec controller tests do not render views by default. In order to render the views, add render_views to the describe block:

    describe 'a POST to :show' do
      render_views
    
      before do
        @bar = Bar.create(foo: 'bar', bar: 'foo')
        post :show, id: @bar
      end
    
      it 'should show bar' do
        expect(response).to be_success
        expect(response.body).to include("<bar>")
      end
    end