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

JMockitを使用してみる

これだけDIコンテナ全盛期だと、Mockフレームワーク
EasyMockで間に合うでしょう。


ですが、依存するクラスのインスタンスをnewしちゃってるような場合は
EasyMockではちょっと難しい。


で、そこでJMockitの登場になります。

バイトコードレベルでMockオブジェクトに入れ替えるので
newしててもおかまいなし。
JVMの引数に追加しなきゃいけないので、
antやmavenを使うときに気をつけなければならないのですが、
かなり強力なMockフレームワークです。


JUnitのサンプルコードは以下のようになります。

public class JMockitAnnotationsExampleTest {
  @Test
  public void testDoOperationAbc() {
    Mockit.setUpMocks(MockDependencyXyz.class);

    Object result = new ServiceAbc().doOperation("test");

    assertNotNull(result);
  }

  @MockClass(realClass = DependencyXyz.class)
  public static class MockDependencyXyz {
    @Mock
    public Object doSomething(String value) {
      return new Object();
    }
  }
}


ServiceAbc#doOperationにて、
DependencyXyzオブジェクトをnewして
DependencyXyz#doSomethingを呼び出す処理を記述しているのですが、
このテストクラス上では、DependencyXyz#doSomethingをMockします。


さらにJMockitではEasyMockのように、記録/再生モードのように
Mockオブジェクトの振る舞いを記述することもできます。

public class JMockitExpectationsExampleTest {
  @Test
  public void testDoOperationAbc() {
    new Expectations(true) {
      @MockField(methods={"doSomething"})
      DependencyXyz mock;

      {
        mock.doSomething("test");
        returns(new Object());
      }
    };

    Object result = new ServiceAbc().doOperation("test");

    assertNotNull(result);
  }
}



new Expectations(true)

の中に、Mockオブジェクトの振る舞いを記述します。
インナークラスを書かなくて良いのでものすごく楽です。




ですが、メソッドの処理をMockするだけでなく
コンストラクタの処理をMockすることも考えられます。


最初のケースでは、publicでstaticな
MockDependencyXyz
のコンストラクタを定義すれば、コンストラクタもMock処理になります。


ですが、Expectationsを使用したケースだと、コンストラクタの処理は
実クラスの処理が呼ばれてしまいます。あれー?
どうすれば良いんだろう?


誰か知ってたらご教示下さい。