web-dev-qa-db-ja.com

JMockitを介してプライベートメソッドを呼び出して結果をテストする

JMockit 1.1を使用していますが、プライベートメソッドを呼び出して、戻り値をテストするだけです。ただし、 JMockit De-Encapsulation の例から、これを行う方法を正確に理解するのに苦労しています。

私がテストしようとしているメソッドは、このクラスのプライベートメソッドです。

public class StringToTransaction {
   private List<String> parseTransactionString(final String input) {
      // .. processing
      return resultList;
   }
}

そして私のテストコードは以下の通りです。

@Test
public void testParsingForCommas() {
   final StringToTransaction tested = new StringToTransaction();
   final List<String> expected = new ArrayList<String>();
   // Add expected strings list here..
   new Expectations() {
      {
         invoke(tested, "parseTransactionString", "blah blah");
         returns(expected);
      }
   };
}

そして私が得ているエラーは:

Java.lang.IllegalStateException:この時点でモック型への呼び出しがありません。このような呼び出しは、適切なモックフィールドまたはパラメータの宣言後にのみ表示されることを確認してください

クラスをモックしたくないので、ここでAPI全体を誤解している可能性があります。プライベートメソッドを呼び出した結果をテストするだけです。

14

あなたはこれを複雑にしすぎていると思います。 Expectationsブロックはまったく使用しないでください。あなたがする必要があるのはこのようなものです:

@Test
public void testParsingForCommas() {
   StringToTransaction tested = new StringToTransaction();
   List<String> expected = new ArrayList<String>();
   // Add expected strings list here..

   List<String> actual = Deencapsulation.invoke(tested, "parseTransactionString", "blah blah");
   assertEquals(expected, actual);
}

基本的には、カプセル化解除を介してプライベートメソッドを呼び出し、実際の値が期待値と等しいことをテストします。メソッドが公開されている場合と同じように。モックは行われていないため、Expectationsブロックは必要ありません。

34
Jeff Olson

現時点では、JMockitを使用できるかどうかはわかりません。私のプライベートメソッドのテストは、昔ながらのリフレクションで行うことができますが、この演習を開始してJMockitについて学びました(そしてコードをテストしました)。 JMockitがこれに使用できない場合は、代わりにリフレクションを使用する方法を次に示します。

_@Test
public void testParsingForCommas() throws Exception {
   StringToTransaction tested = new StringToTransaction();
   ArrayList<String> expected = new ArrayList<>();
   expected.add("Test");

   Method declaredMethod =
         tested.getClass().getDeclaredMethod("parseTransactionString",
               String.class);
   declaredMethod.setAccessible(true);
   Object actual = declaredMethod.invoke(tested, "blah blah");
   assertEquals(expected, actual);
}
_

ここではsetAccessible(true)の呼び出しが重要です。そうしないと、プライベートメソッドを呼び出すときにinvokeが爆発します。

_declaredMethod.setAccessible(true);
_

しかし、あなたは本当にクールなものを知りたいですか? setAccessible(true)を呼び出さないと、_Java.lang.StackOverflowError_で爆発します! :)

3

1.35(?)から開始jmockitはそのヘルパーメソッドを削除しました。それがもはや役に立たないという理由で(私は完全には理解していません)

しかし、はい、このユーティリティは他の場所で利用できます

org.springframework.test.util.ReflectionTestUtils
0
zinking

@Jeff Olsonが述べたように、Beanのプライベートメソッドを宣言して呼び出すこともできます@Tested
例を次に示します。

「ジャワ

@Tested
private YourServiceImplClass serviceImpl;

@Test
public void testPrivateMethod() {

      List<String> expected = new ArrayList<String>();
      // Add expected strings list here..

      List<String> actual = Deencapsulation.invoke(serviceImpl, "yourPrivateMethod", "arguments");
      assertEquals(expected, actual);
}

`` `

0