通过JMockit调用私有方法来测试结果
我使用JMockit 1.1,我想做的就是调用私有方法并测试返回值。 但是,我无法从JMockit De-Encapsulation示例中确切了解如何执行此操作。
我试图测试的方法是这个类中的私有方法:
public class StringToTransaction { private List parseTransactionString(final String input) { // .. processing return resultList; } }
我的测试代码如下。
@Test public void testParsingForCommas() { final StringToTransaction tested = new StringToTransaction(); final List expected = new ArrayList(); // Add expected strings list here.. new Expectations() { { invoke(tested, "parseTransactionString", "blah blah"); returns(expected); } }; }
而我得到的错误是:
java.lang.IllegalStateException:此时缺少对mocked类型的调用; 请确保仅在声明合适的模拟字段或参数后才会出现此类调用
也许我在这里误解了整个API,因为我认为我不想模拟类…只是测试调用私有方法的结果。
我认为你这太复杂了。 您根本不应该使用Expectations块。 你需要做的就是这样:
@Test public void testParsingForCommas() { StringToTransaction tested = new StringToTransaction(); List expected = new ArrayList (); // Add expected strings list here.. List actual = Deencapsulation.invoke(tested, "parseTransactionString", "blah blah"); assertEquals(expected, actual); }
基本上,通过Deencapsulation调用私有方法并测试实际值是否等于预期值。 就像你公开的方法一样。 没有嘲笑,所以不需要Expectations阻止。
此时,我不知道JMockit是否可以或应该用于此。 测试我的私有方法可以使用普通的旧reflection来完成,尽管我开始本练习以了解JMockit(并测试我的代码)。 如果JMockit不能用于此,那么我可以使用reflection代替。
@Test public void testParsingForCommas() throws Exception { StringToTransaction tested = new StringToTransaction(); ArrayList 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
私有方法时invoke
会爆炸。
declaredMethod.setAccessible(true);
但你想知道什么是真的很酷? 如果你不调用setAccessible(true)
,它将会爆发java.lang.StackOverflowError
! 🙂
为什么要直接测试私有方法? 大多数时候API方法即公共接口方法作为私有方法进行unit testing, 也将与它们一起进行间接测试 。 您可以在私有方法中放置具有期望值的断言语句,您可以在公共方法中调用它们。 因此,如果assert失败,您确定私有方法存在一些问题。 所以你不需要单独测试它。