diff --git a/rswag-specs/lib/rswag/specs/request_factory.rb b/rswag-specs/lib/rswag/specs/request_factory.rb index 523b50f..eb13b2d 100644 --- a/rswag-specs/lib/rswag/specs/request_factory.rb +++ b/rswag-specs/lib/rswag/specs/request_factory.rb @@ -194,12 +194,36 @@ module Rswag def build_json_payload(parameters, example) body_param = parameters.select { |p| p[:in] == :body }.first - body_param ? example.send(body_param[:name]).to_json : nil + + return nil unless body_param + + raise(MissingParameterError, body_param[:name]) unless example.respond_to?(body_param[:name]) + + example.send(body_param[:name]).to_json end def doc_version(doc) doc[:openapi] || doc[:swagger] || '3' end end + + class MissingParameterError < StandardError + attr_reader :body_param + + def initialize(body_param) + @body_param = body_param + end + + def message + <<~MSG + Missing parameter '#{body_param}' + + Please check your spec. It looks like you defined a body parameter, + but did not declare usage via let. Try adding: + + let(:#{body_param}) {} + MSG + end + end end end diff --git a/rswag-specs/spec/rswag/specs/request_factory_spec.rb b/rswag-specs/spec/rswag/specs/request_factory_spec.rb index aff5fb4..a26f694 100644 --- a/rswag-specs/spec/rswag/specs/request_factory_spec.rb +++ b/rswag-specs/spec/rswag/specs/request_factory_spec.rb @@ -160,6 +160,21 @@ module Rswag end end + context 'missing body parameter' do + before do + metadata[:operation][:parameters] = [{ name: 'comment', in: :body, schema: { type: 'object' } }] + allow(example).to receive(:comment).and_raise(NoMethodError, "undefined method 'comment'") + allow(example).to receive(:respond_to?).with(:'Content-Type') + allow(example).to receive(:respond_to?).with('comment').and_return(false) + end + + it 'uses the referenced metadata to build the request' do + expect do + request[:payload] + end.to raise_error(Rswag::Specs::MissingParameterError, /Missing parameter 'comment'/) + end + end + context 'form payload' do before do metadata[:operation][:consumes] = ['multipart/form-data']