回答編集履歴
1
test環境に特化した条件を判断するためのより良いアルゴリズムを実装した。
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
|
-
|
18
|
+
なお、成功をテストする場合にはID=0 になることはあり得ない、ことを保証するよう、気をつけましょう(Rails用のDBのデフォルト設定では、IDは1から始まるのでこの条件は満たされているでしょう)。
|
19
19
|
|
20
20
|
現実には、このようにテストのそれも特定の条件の時だけ呼ばれる行を、実際の Controllerのコードの中に含ませることはあまりよいpracticeとは言えないかも知れませんが。
|
21
21
|
それを避けるためには、たとえばそのようなtestsを一度実行して期待通りの挙動であることを確認した後、ソースコードの中から該当行をコメントアウトする(必要ならばテストコードからもコメントアウトする)、ようにした方がいいかもしれませんか。
|