Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test ActiveModel::Serializer classes with Rspec

Given the following ActiveModel::Serializer class:

class SampleSerializer < ActiveModel::Serializer
  attributes :id, :name
end

How can this be tested with RSpec?

like image 236
gnerkus Avatar asked Feb 13 '16 03:02

gnerkus


2 Answers

Assumptions

This answer assumes you have the rspec-rails, active_model_serializers and factory_girl_rails gems installed and configured.

This answer also assumes you have defined a factory for the Sample resource.

Serializer spec

For the current version(0.10.0.rc3) of active_model_serializers at the time of writing, ActiveModel::Serializer classes do not receive to_json and are , instead, wrapped in an adapter class. To obtain the serialization of a model wrapped in a serializer instance, an instance of an adapter must be created:

before(:each) do
  # Create an instance of the model
  @sample = FactoryGirl.build(:sample)

  # Create a serializer instance
  @serializer = SampleSerializer.new(@sample)

  # Create a serialization based on the configured adapter
  @serialization = ActiveModelSerializers::Adapter.create(@serializer)
end

The adapter instance receives the to_json method and returns the serialization of the model.

subject { JSON.parse(@serialization.to_json) }

Expectations can then be run on the JSON returned.

it 'should have a name that matches' do
  expect(subject['name']).to eql(@sample.name)
end

When parsing the JSON response, the adapter configuration must be taken into consideration:

  • The default config, :attributes, generates a JSON response without a root key:

    subject { JSON.parse(@serialization.to_json) }
    
  • The :json config generates a JSON response with a root key based on the model's name:

    subject { JSON.parse(@serialization.to_json)['sample'] }
    
  • The :json_api config generates a JSON that conforms to the jsonapi standard:

    subject { JSON.parse(@serialization.to_json)['data']['attributes'] }
    
like image 110
gnerkus Avatar answered Nov 14 '22 22:11

gnerkus


When using active_model_serializers, there is a much easier way by simply calling serializable_hash on the serializer:

it 'should include a correct name' do
  sample = FactoryBot.create(:sample)
  serializer = SampleSerializer.new(sample)
  expect(serializer.serializable_hash[:name]).to eq 'Heisenberg'
end
like image 30
Jan Klimo Avatar answered Nov 14 '22 22:11

Jan Klimo