JMockitでExpectationsを定義している箇所でUnexpectedInvocationが発生する

[前提知識]
Expectationsを用いる事で、実行した順序に処理が行われているかを検証する事ができる。
また、検証順序を定義する際、定義したメソッドのすぐ後ろに
 result = 任意のオブジェクト
と書くことでreturnで返ってくるオブジェクトをすり替えることができる。

(参考URL)
JMockit使い方メモ - Qiita


[事象]
JMokitでExpectationsを用いてメソッドの実行順序を確認するテストケースを実行したが、
UnexpectedInvocationが発生してしまう。
以下の様なエラーログが発生する。

mockit.internal.UnexpectedInvocation: Unexpected invocation of //①
javax.faces.context.FacesContext#getApplication() //②
 on instance: jp.hoge.taghandler.component.$Subclass_context@2eda0950
when was expecting an invocation of:
javax.el.ExpressFactory#createMethodExpression(javax.el.ELContext, String, Class, Class[]) //③
 with argments: any javax.el.ELContext, "{hogeBean.executeEvent(\"item1\")}", any Class, any Class[] //④
 on mock instance: jp.hoge.taghandler.component.$Subclass_ef@706a04ae
  at jp.hoge.taghandler.component.UIComponentCustom(UIComponentCustom:999) //⑤
//以下、略

[エラーログの見方]
①想定しているメソッドとは異なるメソッドが実行されて怒られている
JUnitで実際に実行されているメソッド
JUnitに記述している実行される想定であるメソッドのシグニチャ
JUnitに記述している実行される想定であるメソッドに与えているパラメータ
⑤実行されているメソッドが定義されているクラス及びエラー箇所
 そのため、②や⑤を手掛かりに実際のソースを確認し、③や④と異なる箇所が存在しないかを確認する

[なかなか気づかなかった原因]
・想定している引数が異なる
 単純に方が異なるケースや、オーバロードメソッドが呼ばれており、「実行しているメソッドは合っているのになぁ」と気づかないことがあった。

・実行しているメソッドが異なる
 引数は全く同じなのに、実行しているメソッドが異なっていた。
 メソッド名が実行を想定していたメソッドと非常に似ていて気づかないことがあった。

・メソッド名は同じだが、それを実行しているクラスが異なる
 Aクラスのaメソッドを実行される想定のテストケースを記述していたが、実際にはBクラスのaメソッドが実行されていた。
 これもメソッド名が同じであったがためになかなか気づかなかった。

・同じメソッドが複数回呼ばれていた
 (テストコードもしくは実コードが悪いだけという場合もあるが、)
 想定しているメソッドが複数回呼ばれるにも関わらず、Expectations内では一回しか検証を宣言していなかった。
 なお、複数回実行されることを定義する場合は、同じメソッドを複数回並べるのでもそれは構わないが、times = 3;と書けば3回実行される想定という事になる。
 (暗黙的にはtimes = 1;と書かれていると思えば理解しやすい。)

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

  • 作者:渡辺 修司
  • 発売日: 2012/11/21
  • メディア: 単行本(ソフトカバー)
実践 JUnit ―達人プログラマーのユニットテスト技法

実践 JUnit ―達人プログラマーのユニットテスト技法