ruby on rails, tests, rspec, jbuilder

How to RSpec a Jbuilder response from a Rails JSON API

How to RSpec a Rails JSON API responses with Jbuilder

How to RSpec a Rails JSON API responses with Jbuilder

Want to write a Rails API controller test and make sure it includes exactly what your Jbuilder serializer returns? You need to enable `render_views`. Learn why in this post.

For rspec-rails users, when testing a controller action that uses Jbuilder as a serializer, and you want to test that the response includes exactly what you expect from the Jbuilder serializer, you need to enable render_views in your specs.

That’s because in RSpec, rendering the content of view templates is disabled by default.

But when using Jbuilder, you do want to render views because that’s how Jbuilder serializes the response. And that’s what render_views does: it enables view rendering for controllers specs.

What’s the difference between render_template and render_views?


Allows the template to be rendered, but not the content itself. The response body is an empty string. This is the default configuration in RSpec. It allows you to assert expect(response).to render_template("index").


Allows rendering the contents of the template. This allows us to inspect the JSON response: expect(response.body).to eq "{email: ""}".

Testing JSON API responses serialized by Jbuilder in Rails

Let’s see an example:

# app/api/v1/users/active_users_controller.rb

def index
  @users =

In the view/serializer, we extract only the attributes we want from an user:

# app/views/api/v1/users/active_users/index.json.jbuilder

json.array! @users do |user|
  json.extract! user,

How to test a Rails Controller JSON response with RSpec

Let’s verify our API response is returning exactly what we want:

RSpec.describe Api::V1::ActiveUsersController, type: :controller do
  render_views # <- you need to add this!

  describe "GET /index.json" do
    it "returns a JSON response with the attributes specified in the jbuilder serializer" do
      get :index, format: :json

      parsed_body = JSON.parse(response.body)

        .to contain_exactly("email", "full_name", "last_sign_in_at")


Add render_views as a global RSpec configuration

In your rails_helper, add:

RSpec.configure do |config|

Keep in mind that disabling render_views in a spec group, overrides the global configuration.

Add format:json to your JSON routes

If your API routes namespace doesn’t already enforce json as the format, enforce them individually:

resources :active_users, only: [:index], defaults: { format: 'json' }

To save others time when they run into this situation, I opened a PR on Jbuilder to include this extra configuration in their documentation.

And that’s it! Now you can sleep well at night knowing that your Jbuilder serializer is rendering exactly what you want, and nothing more than that 🛌💤.