ファイルのアップロード機能を作っていて、テストの書き方がわからなかったので調べた結果をメモ。アップロード処理は次のようになっています。

  1. ブラウザがファイルを Post
  2. コントローラが Post データを受け取り、モデルに渡す
  3. モデルがデータをファイルに保存

行いたいテストはコントローラのテストとモデルのテストの2種類。

まずコントローラのテスト。ActionController::TestUploadedFileを使う模様。
83’s : ファイルアップロードのテスト

次にモデルのテスト。

ファイルがアップロードされたかテストするためには、cgi.rbがマルチパートのPOSTを受け取ったときの処理を模擬する必要がある。 困ったことに、そこでやることは結構長くて複雑だ。 ファイルをシステムに取り込んで、いつもcgi.rbから取り出している形式に変換する。 もちろんどんなメソッドを持つかは場合による。

定義 (test_helper.rb):

def uploaded_file(tmp_filename, content_type, filename)
t = Tempfile.new(filename);
t.binmode
path = RAILS_ROOT + “/test/fixtures/files/” + tmp_filename
FileUtils.copy_file(path, t.path)
(class << t; self; end).class_eval do alias local_path path define_method(:original_filename) { filename } define_method(:content_type) { content_type } end return t end [/sourcecode] RoR Wiki 翻訳 Wiki – HowtoUploadFiles より

通常、Post データがモデルに渡るときには TempFile クラスのオブジェクトで渡され、しかもオブジェクトは cgi.rb によて拡張されているんだと思います。そのため、データを保存するモデルをテストするには、cgi.rb と同様の拡張をほどこしてくれるヘルパ関数を test_helper.rb に定義しています。

以上でコントローラ、モデルともにテストできます。

広告