結論から言うと以下のように呼び出すことが出来ます。
バージョンは rspec (3.11.0) です。
RSpec.describe MyClass do
let(:integration_test) { ActionDispatch::IntegrationTest.new(nil) }
context do
it do
integration_test.get('/path/to')
expect(integration_test.response.status).to be 200
end
end
end
Request spec 以外のクラスのテストでどうしても API を呼び出した結果のレスポンスが欲しい場合、どうやって呼び出すか調べてみました(そもそもそういうテストは書くべきでないという話は置いといて)。
Request spec 内で binding.pry
して止めてみます。
RSpec.describe MyController, type: :request do
it do
binding.pry
end
end
get
がどこで定義されているか調べてみます。
> method(:get).source_location
=> ["/Users/kurashita/TestApp/vendor/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/testing/integration.rb", 369]
以下に定義されていることがわかりました。
TestApp/vendor/bundle/ruby/3.0.0/gems/actionpack-6.1.6/lib/action_dispatch/testing/integration.rb
%w(get post patch put head delete cookies assigns follow_redirect!).each do |method|
# reset the html_document variable, except for cookies/assigns calls
unless method == "cookies" || method == "assigns"
reset_html_document = "@html_document = nil"
end
definition = RUBY_VERSION >= "2.7" ? "..." : "*args"
module_eval <<~RUBY, __FILE__, __LINE__ + 1
def #{method}(#{definition})
#{reset_html_document}
result = integration_session.#{method}(#{definition})
copy_session_variables!
result
end
RUBY
end
ActionDispatch::Integration::Runner
モジュールに動的に定義されているようです。
このモジュールは ActionDispatch::IntegrationTest
でインクルードされているのでこれをインスタンス化すれば使えそう、というところであとは継承してるクラスをたどって行くだけなので割愛します。
ちなみに以下のコードで、
actionpack-6.1.6/lib/action_dispatch/testing/integration.rb#L368
module_eval <<~RUBY, __FILE__, __LINE__ + 1
def #{method}(#{definition})
#{reset_html_document}
result = integration_session.#{method}(#{definition})
copy_session_variables!
result
end
RUBY
integration_session
の同名のメソッドを呼んでおり、この中身は ActionDispatch::Integration::Session
クラスのインスタンスなのでこれを呼ぶことでも使用可能です。
let(:session) { ActionDispatch::Integration::Session.new(Rails.application) }
it do
session.get('/path/to')
end