How to test rack middleware

ざざっとメモ。

Middlewareの種類

一口に Rack middleware と言っても目的とする動作にはいくつかバリエーションがある。

  1. request を処理する middleware
  2. response を処理する middleware
  3. その他を処理する middleware ( middleとは? )

例えば Rack::Access や Rack::Cors, OmniAuth はアプリに到達する前の request を処理する middleware であり、Rack::ETag や Rack::Deflator は response を処理するものである。ExceptionNotification などはその他を処理する middleware である。

基本的にアプリは適当でよい

例えばこんな感じだ。

  • 適当な lambda を作って名前を付ける(#callを呼べればなんでもよい)
  • rspec や minitest/spec では let でもよい

この時に大事なのは、例外を起こす lambda にするか、あるいは期待する値を返す lambda にするかなど、「気にしていることだけを実現する lambda」を雑に作ってしまってよいということだ。Rails アプリであろうがなかろうが Rack middleware のレベルでは status code と headers と body の三つが揃っているというただそれだけのものになる。

テストしたいアプリをbuildする

テストしたい middleware を use してテストしたい条件の lambda を run するアプリを build する。

Rack::Builder.new do
  use Middleware
  run Application
end

これを call すれば Rack middleware のテストは行える。

テストで気にするものについて十分なパターンを用意する

  • request を処理するなら env のパターンが豊富になる1
  • response を処理するならアプリの lambda をいくつも用意する
  • その他の場合も恐らくアプリの lambda の準備を厚くする形になるだろう

例えば ExceptionNotification のようなものをテストしたいのであれば

Rack::Builder.new do
  use Middleware
  run lambda { |env| raise StandardError }
end

みたいなものが必要になる。

参考

  1. request の path や何らかの header について該当するかしないかのパターンを用意することになるはずだ。 

More