Given the following ActiveModel::Serializer
class:
class SampleSerializer < ActiveModel::Serializer
attributes :id, :name
end
How can this be tested with RSpec
?
Given the following ActiveModel::Serializer
class:
class SampleSerializer < ActiveModel::Serializer
attributes :id, :name
end
How can this be tested with RSpec
?
Example: You can writing this modern style.
Category serializer:
RSpec:
When using active_model_serializers, there is a much easier way by simply calling
serializable_hash
on the serializer:@gnerkus’s answer helped to guide my own implementation, but I chose a different approach. Testing the returned values of
ActiveModel::Serializer
where no additional processing is being done by the Serializer seems to be testing both the presence of particular keys and whetherActiveModel::Serializer
is working. To avoid testingActiveModel::Serializer
and instead test whether specific keys are present, here’s how I would test a given Serializer:Notice the use of
contain_exactly
: this ensures that no other keys than the ones you specify are present. Usinginclude
would result in tests not failing if unexpected attributes are included. This scales nicely when you update the attributes but fail to update your tests, as the test will throw an error and force you to keep everything up to date.The exception to testing keys only would be when you want to test custom methods you’ve added to a given serializer, in which case I would highly recommend writing a test for the returned value/s impacted by that method.
Update
For testing relationships, you'll need to do a little more setup with the serializer. I avoid this setup for simple serializers, but this modified setup will help you test the presence of links, relationships, etc.
Assumptions
This answer assumes you have the
rspec-rails
,active_model_serializers
andfactory_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 receiveto_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:The adapter instance receives the
to_json
method and returns the serialization of the model.Expectations can then be run on the JSON returned.
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:The
:json
config generates a JSON response with a root key based on the model's name:The
:json_api
config generates a JSON that conforms to the jsonapi standard: