読者です 読者をやめる 読者になる 読者になる

ぽかぽかウンティの自由帳

ぽかぽか動物園から投稿します。

ruby で carrierwave を使って画像アップロードする rspec テストに悩む

carrierwaveuploader/carrierwave · GitHub

が便利だから画像アップロード周りはそれに頼っている。

画面からでも rake task からでも簡単に画像アップロードできる。

しかし rspec でそれをテストしようとした際に、いったいどこまでテストダブルを使ってやればいいのか迷った。

File.open とか FileList.[] とかを一生懸命 stub 指定したけど、結局 carrierwave 内部で何をやっているのか把握しないといけないのが面倒だったから、/tmp を使うことにした。

そこでテスト用の画像ファイルが必要になるのだが、/tmp に指定画像を置く前提でテストを書くわけにもいかないので、画像ファイルは before(:each) で毎回生成する形にした。

んで画像ファイルを文字列化して let(:data) に貼り付けようとしたけど、ruby でバイナリと文字列の変換ってどうやるんだろうとググったら、Array#pack と String#unpack を使えと書いてあった。

まず、irb や pry や rails c でテキトーな画像ファイルを読み込む。

binbin = File.binread "/tmp/origin_image.gif"

コンソールにはドバーって文字列が出力されるが無視して、16進数で文字列変換する。H のとなりのアスターはバイト指定で全部の意。

hexhex = binbin.unpack "H*"
# Array が返る

またコンソールにドバーって出力されるから、今度はそれをコピペして使う。

テスト側でバイナリに戻したいときは以下。

binbinbin = hexhex.pack "H*"
# hexhex は Array、String に unpack メソッドはない

それをファイルに書き出す。

File.binwrite "/tmp/test_image.gif", binbinbin