テスト用にRoutingを動的にいじってテストしたいことがたまにあるのでやり方をメモ📝
まず以下のようなテスト用のhelperを用意します。
中でやっていることは動的にrouteを追加するdraw_test_routes
とそれをリセットするreload_routes!
を実装しています。
module RoutesHelper def draw_test_routes(&block) Rails.application.routes.disable_clear_and_finalize = true Rails.application.routes.draw do instance_exec(&block) end end def reload_routes! Rails.application.reload_routes! end end
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" class TestsController < ActionController::Base def index head :ok end end describe "GET /test", type: :request do include RoutesHelper before(:example) do draw_test_routes do get "/tests", to: "tests#index" end end after(:example) do reload_routes! end it "success" do get "/tests" expect(response).to have_http_status :ok end end