Tech Sketch Bucket of Technical Chips by TIS Inc.

RSpec Tips -- ブロック付きメソッドを stub 化する --

Pocket

この記事はeXcale Developer's Blogから移転されたものです。


eXcale 開発チームの冨樫です。

Ruby のテストフレームワークで人気の RSpec について、ハマりそうな点や知っておくと便利な機能をご紹介致します。
今回は「ブロック付きメソッドの stub 化」です。ブロック付きメソッドは each や map だけでなく、ファイルやネットワークを介した操作をするとき等、様々な場面で使用されるので、この stub 化については役立てる機会が多いかと思います。


eXcaleでは期間限定でサインアップキャンペーン実施中です。
キャンペーン内容についてはこちらを参照してください。


今回ご紹介する内容の題目です

  • ブロック付きメソッドを stub 化する
  • ブロック処理内で stub 化したオブジェクトを使用する
  • ブロック処理内で任意のメソッドを実行する

ブロック付きメソッドを stub 化する

早速ですが、テスト対象のメソッドを見て行きましょう。
ディレクトリ内に "hoge.txt" が存在しているかを確認するメソッドです。

2行目の each メソッドをブロック付きで呼び出しています。
これを stub 化します。

といっても and_yield を使用することで簡単に行えます。
テストコードを見てください。

注目は3行目です。
and_yield を使い、 eachのブロック処理に対して "hoge.txt" を渡しています。
※ stub_chain は連続でメソッドを呼び出している箇所を stub にしてくれる便利機能です。

テストを実行すると、正常終了することが確認できます。
コンソールには "hoge.txt" が出力されており、ブロック付きメソッドも問題無く実行されていることが確認できます。

また、ブロック処理を複数回実行したい場合は and_yield を複数記載することで対応できます。

テスト実行後、コンソール画面で確認すると
----
fuga.txt
hoge.txt
----
と出力され、ブロック処理が複数回実行されていることが確認できます。


ブロック処理内で stub 化したオブジェクトを使用する

単純な例だけではつまらないので、ちょっと応用パターンも見ていきましょう。
下記は、FTPでファイルをダウンロードするメソッドです。

2行目のブロック付きメソッドを呼び出している箇所を、同様に stub 化します。

気をつける点として、3行目のブロックの処理では、渡された sftpオブジェクト に対して download! メソッドを実行しているため、and_yield で渡す値は download! メソッドを持つオブジェクトである必要があります。

では上記を踏まえて、テストコードを見ていきましょう。

3〜4行目で、 and_yield に渡している sftp オブジェクトを stub 化し、 download! メソッドを持たせています。
こうすることで download! が実行されても例外を発生させること無く、テストを実施させることができます。

ブロック処理内で任意のメソッドを実行する

次に、ダウンロードだけでなく、後続処理でダウンロードしたファイルを参照する場合について見てみましょう。メソッドは以下になります。

ここで問題となるのが、5行目のファイル読込です。
ダウンロードしたファイルを参照しているため、実際にファイルが無いと "No such file or directory" の例外が発生してしまいます。

File.open も stub 化させれば例外は抑える事ができますが、
ここでは stub 化させない方法で対応してみようと思います。

テストコードです。

sftp オブジェクトは stub 化させずに download! メソッドをテスト側で実装しているところがポイントです。

実際にファイルが作成されるため、あたかもダウンロードされたように振る舞えるので、ダウンロード処理後に何かファイルを参照する処理が実装されていても、それらは stub 化させる必要はありません。

※ 上記テストを実装した際は、ゴミファイル(./foo.txt)が残るので、after 処理で削除することをお忘れなく。


最後に

今回は ブロック付きメソッドの stub 化について複数パターンご紹介させて頂きました。
テストコードは面倒ですが、怠けてるとそのうち自分に返ってくるので、便利機能を駆使して負けじと書いて行きましょう。

テストがお済みのアプリがありましたら、是非 eXcale へデプロイしてください。
操作手順は簡単なのでお気軽にお試し頂けます(基本無料です)。

※ サインアップからデプロイまでの流れは こちらのブログ で手順を紹介しているので、ご参照ください。

エンジニア採用中!私たちと一緒に働いてみませんか?