Rspecは便利。Railsを使っているのにRspecを使っていない人はニワカか変態です。
RspecはMockやFeature等様々なテストを記述することができるものの、外部システムが落ちてしまっているときのテストを行うのは難しい。
かと言ってここを手作業でやっても仕方がない。
今回は、RspecでDBサーバが落ちてしまったケースを想定したテストをする。
DB接続失敗した際に特定のHTTPステータスコードを返すといった仕様があるとして、そのテストを行う方法を書き溜める。
リクエストの直前に別のDBに接続してしまうという方法。
config/database.ymlに存在しない接続先を設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# config/database.yml default: &default adapter: postgresql encoding: utf8 host: <%= ENV.fetch("DATABASE_HOST") %> database: <%= ENV.fetch("DATABASE_NAME") %> username: <%= ENV.fetch("DATABASE_USER") %> password: <%= ENV.fetch("DATABASE_PASSWORD") %> pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 16 } %> timeout: <%= ENV.fetch("RAILS_DATABASE_TIMEOUT") {5000} %> port: 5432 test: <<: *default error_db: <<: *default host: no_host database: testdb |
後はこの接続先にリクエスト直前につないでしまう。
1 2 3 4 5 6 7 8 9 10 11 |
it '544エラーが返ること' do # ホスト名が存在しないDBに対して接続する ActiveRecord::Base.establish_connection :error_db get '/hello' # 元のDBに接続し直す ActiveRecord::Base.establish_connection :test @json = JSON.parse(response.body) expect(response.status).to eq 544 expect(@json['message']).to eq 'Internal Server Error' end |
リクエスト後に、テスト用のDBに再接続することを忘れないように。忘れると以降のRspecが全部失敗します。
このやり方にも課題はあって、処理中にDBが停止したとかのテストはできない。