ruby on rails - tutorial - Prueba las clases ActiveModel:: Serializer con Rspec
should not validate rspec (4)
Dada la siguiente clase ActiveModel::Serializer
:
class SampleSerializer < ActiveModel::Serializer
attributes :id, :name
end
¿Cómo se puede probar esto con RSpec
?
Suposiciones
Esta respuesta asume que tienes las rspec-rails
, active_model_serializers
y active_model_serializers
instaladas y configuradas.
Esta respuesta también asume que ha definido una fábrica para el recurso de Sample
.
Especificación serializador
Para la versión actual (0.10.0.rc3) de active_model_serializers en el momento de la escritura, las clases ActiveModel::Serializer
no reciben to_json
y, en cambio, están envueltas en una clase de adaptador. Para obtener la serialización de un modelo envuelto en una instancia de serializador, se debe crear una instancia de un adaptador:
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
La instancia del adaptador recibe el método to_json
y devuelve la serialización del modelo.
subject { JSON.parse(@serialization.to_json) }
Las expectativas se pueden ejecutar en el JSON devuelto.
it ''should have a name that matches'' do
expect(subject[''name'']).to eql(@sample.name)
end
Al analizar la respuesta JSON, se debe tener en cuenta la configuración del adaptador:
La configuración predeterminada,
:attributes
, genera una respuesta JSON sin una clave raíz:subject { JSON.parse(@serialization.to_json) }
El
:json
config genera una respuesta JSON con una clave raíz basada en el nombre del modelo:subject { JSON.parse(@serialization.to_json)[''sample''] }
La configuración
:json_api
genera un JSON que cumple con el estándar jsonapi :subject { JSON.parse(@serialization.to_json)[''data''][''attributes''] }
Al usar active_model_serializers , hay una forma mucho más fácil simplemente llamando serializable_hash
en el serializador:
it ''should include a correct name'' do
sample = FactoryGirl.create(:sample)
serializer = SampleSerializer.new(sample)
expect(serializer.serializable_hash[:name]).to eq ''Heisenberg''
end
Ejemplo: Puedes escribir este estilo moderno.
Categoría serializador:
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name
end
RSpec:
require ''rails_helper''
RSpec.describe CategorySerializer, type: :serializer do
let(:category) { FactoryGirl.build(:category) }
let(:serializer) { described_class.new(category) }
let(:serialization) { ActiveModelSerializers::Adapter.create(serializer) }
let(:subject) { JSON.parse(serialization.to_json) }
it ''has an id that matches'' do
expect(subject[''id'']).to eql(category.id)
end
it ''has a name that matches'' do
expect(subject[''name'']).to eql(category.name)
end
end
La respuesta de @gnerkus ayudó a guiar mi propia implementación, pero elegí un enfoque diferente. La prueba de los valores devueltos de ActiveModel::Serializer
donde el ActiveModel::Serializer
no realiza ningún procesamiento adicional parece estar comprobando la presencia de teclas particulares y si ActiveModel::Serializer
está funcionando. Para evitar probar ActiveModel::Serializer
y, en su lugar, probar si hay teclas específicas presentes, así es como probaría un Serializer determinado:
describe SampleSerializer do
subject { SampleSerializer.new(sample) }
it "includes the expected attributes" do
expect(subject.attributes.keys).
to contain_exactly(
:sample_key,
:another_sample_key
)
end
def sample
@sample ||= build(:sample)
end
end
Observe el uso de contain_exactly
: esto garantiza que no haya otras claves distintas de las que usted especifique. Si se usa include
, las pruebas no fallarán si se incluyen atributos inesperados. Esto se ajusta muy bien cuando actualiza los atributos pero no actualiza sus pruebas, ya que la prueba arrojará un error y lo obligará a mantener todo actualizado.
La excepción a las claves de prueba solo sería cuando desea probar los métodos personalizados que ha agregado a un serializador determinado, en cuyo caso le recomiendo que escriba una prueba para los valores devueltos afectados por ese método.
Actualizar
Para probar las relaciones, deberá configurar un poco más con el serializador. Evito esta configuración para los serializadores simples, pero esta configuración modificada le ayudará a probar la presencia de enlaces, relaciones, etc.
describe SampleSerializer do
subject do
ActiveModelSerializers::Adapter.create(sample_serializer)
end
it "includes the expected attributes" do
expect(subject_json(subject)["data"]["attributes"].keys).
to contain_exactly(
"date"
)
end
it "includes the related Resources" do
expect(subject_json(subject)["data"]["relationships"].keys).
to contain_exactly(
"other-resources"
)
end
def subject_json(subject)
JSON.parse(subject.to_json)
end
def sample_resource
@sample_resource ||= build(:sample_resource)
end
def sample_serializer
@sample_serializer ||=
SampleSerializer.new(sample_resource)
end
end