テスト用にRoutingを動的にいじってテストしたいことがたまにあるのでやり方をメモ📝
まず以下のようなテスト用のhelperを用意します。
中でやっていることは動的にrouteを追加するdraw_test_routes
とそれをリセットするreload_routes!
を実装しています。
moduleRoutesHelperdefdraw_test_routes(&block) Rails.application.routes.disable_clear_and_finalize = trueRails.application.routes.draw do instance_exec(&block) endenddefreload_routes!Rails.application.reload_routes! endend
Rails.application.routes.disable_clear_and_finalize = true
をすることで以下のroutesのclearやfinalizeを無効化してroutesを固定化させず、動的に追加したものを初期化させないようにします。
またRails.application.reload_routes!
を実行することで、clear!
し再読み込みされfinalize!
することで動的に追加したroutesを削除するとともにRails.application.routes.disable_clear_and_finalize
がfalseに再設定されるので、元に戻ります。
https://github.com/rails/rails/blob/v7.1.2/railties/lib/rails/application/routes_reloader.rb#L22-L29
以下の通り、任意のcontrollerを使って動的にrouteを追加することができました🎉
require"spec_helper"require_relative"../../test/support/routes_helper"classTestsController< ActionController::Basedefindex head :okendend describe "GET /test", type: :requestdoincludeRoutesHelper before(:example) do draw_test_routes do get "/tests", to: "tests#index"endend after(:example) do reload_routes! end it "success"do get "/tests" expect(response).to have_http_status :okendend