7

RailsコントローラーからのJSON応答をレンダリングするために、アクティブモデルシリアライザーを使用しています。

次のようなコントローラー アクションがあります。

def show
  @foo = Foo.find(params[:id])
  if @foo.user == current_user
    render json: @foo, serializer: FooSerializer
  else
    render json: @foo, serializer: TrimmedFooSerializer
  end
end

Rspec コントローラーのテストで使用されたシリアライザーをテストできるようにしたいと考えています。テストからシリアライザーへの参照を取得することは可能ですか?

アップデート:

これはシリアライザの正しい使い方ではないと思います。シリアライザー自体に、条件付きで属性を含めるためのロジックが追加されました。コントローラーは、どのシリアライザーを使用するかを気にする必要はありません。

4

4 に答える 4

14

誰かが返信してからしばらく経ちましたが、将来のグーグル社員がこれを見つけた場合に備えて、私は次のアプローチが好きです:

RSpec::Matchers.define :serialize_object do |object|
  match do |response|
    @serializer_klass.new(object).to_json == response.body
  end

  chain :with do |serializer_klass|
    @serializer_klass = serializer_klass
  end
end

次に、テストで次のことができます。

expect(response).to serialize_object(claim).with(ClaimSerializer)

shoulda はすでにその名前のマッチャーを定義しているため、マッチャーを「シリアル化」とは呼びませんでした。

于 2014-10-20T03:06:58.400 に答える
1

Knightstickが上記で行ったことを参考にして、エラー メッセージなどを少し改善し、単一のリソースまたはリソース コレクションの両方を処理する機能を追加しました (私は active_model_serializers gem、バージョン 0.10.0 を使用しています)。

RSpec::Matchers.define :serialize_resource do |resource|
  match do |response|
    serialized_json(resource) == response.body
  end

  chain :with do |serializer_klass|
    @serializer_klass = serializer_klass
  end

  failure_message do |response|
    "expected response body #{serialized_json(resource).inspect}, got #{response.body.inspect}"
  end

  def serialized_json(resource)
    options = if resource.is_a?(Array)
                { each_serializer: @serializer_klass }
              else
                { serializer: @serializer_klass }
              end

    serializable = ActiveModelSerializers::SerializableResource.new(resource, options)
    serializable.serializable_hash.to_json
  end
end
于 2017-05-15T21:29:55.093 に答える