teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

test環境に特化した条件を判断するためのより良いアルゴリズムを実装した。

2021/11/30 20:13

投稿

MasaSakano
MasaSakano

スコア188

answer CHANGED
@@ -7,15 +7,15 @@
7
7
  もしそのような組合わせが存在せず、よほど奇妙な事態(たとえば、Databaseへの接続が物理的に突然絶たれるなど)でない限りは失敗するはずがない場合は、敢えてエラーを起こすのは容易ではないと思います。
8
8
  力技でよければ、以下の方法が考えつきました。
9
9
 
10
- 端的には、ある特定の条件において、陽に失敗させます。たとえば、`begin`文の後もしくは`agreement.update_attribute`の直前に、次の一行を加えます。
10
+ 端的には、test環境におけるある特定の条件において、陽に失敗させます。たとえば、`begin`文の後もしくは`agreement.update_attribute`の直前に、次の一行を加えます。
11
11
 
12
12
  ```ruby
13
- raise 'my-error' if 0 == params[:id].to_i
13
+ raise 'my-error' if Rails.env.test? && 0 == params[:id].to_i
14
14
  ```
15
15
 
16
16
  そして、テストの時、ID=0のデータをDBに作って、そのIDをテストの時に呼びます。そうすると、`RuntimeError`で失敗します。あるいは、IF文中で`agreement = nil`とすれば`NoMethodError`例外により`update_attribute`が失敗しますし、`agreement.freeze`にすれば`FrozenError` 例外が出て失敗します。
17
17
 
18
- もちろんアプリ普通使えば、このID=0 は決してあり得ない、のが必須条件です(Rails用のDBのデフォルト設定では、IDは1から始まるのでこの条件は満たされているでしょう)。
18
+ なお成功テストする場合ID=0 になることはあり得ない、ことを保証るよう、気をつけましょう(Rails用のDBのデフォルト設定では、IDは1から始まるのでこの条件は満たされているでしょう)。
19
19
 
20
20
  現実には、このようにテストのそれも特定の条件の時だけ呼ばれる行を、実際の Controllerのコードの中に含ませることはあまりよいpracticeとは言えないかも知れませんが。
21
21
  それを避けるためには、たとえばそのようなtestsを一度実行して期待通りの挙動であることを確認した後、ソースコードの中から該当行をコメントアウトする(必要ならばテストコードからもコメントアウトする)、ようにした方がいいかもしれませんか。