通过JMockit调用私有方法,测试结果(Invoking a private method via

2019-08-17 22:27发布

我使用JMockit 1.1和所有我想要做的就是调用私有方法和测试返回值。 然而,我无法确切地了解如何从做这个JMockit解封装的例子。

我想测试的方法是在这个类的私有方法:

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,因为我不认为我需要模拟类..只是测试调用私有方法的结果。

Answer 1:

我认为你正在这个太复杂了。 你不应该使用的期望阻止的。 所有你需要做的是这样的:

@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);
}

基本上,经由Deencapsulation调用一个私有方法和测试实际等于预期。 就像你,如果该方法是公开的。 无嘲讽正在做,所以不需要期望块。



Answer 2:

在这一点上,我不知道是否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 ! :)



Answer 3:

从1.35(?)jmockit删除的helper方法开始。 对于它不再有用的原因(我不太明白)

但是,是的,这个工具可以在别处

org.springframework.test.util.ReflectionTestUtils


Answer 4:

正如@Jeff奥尔森提到的,你也可以通过声明呼吁他们bean的私有方法@Tested
下面是一个例子:

```的java

@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);
}

```



Answer 5:

你为什么要直接测试私有方法? 大多数时候API方法,即公共接口方法单元测试的私有方法将间接地与他们一起测试也是如此。 你可以把断言与从那里你给他们打电话的公共方法中的私有方法的预期值语句 。 所以,如果断言失败,你肯定有一些问题与私有方法。 所以您无需单独测试。



文章来源: Invoking a private method via JMockit to test result