如何在不实际调用其子方法的情况下模拟方法调用

时间:2015-09-23 08:23:54

标签: java unit-testing junit mockito

我从昨天开始使用JUnits(Mockito)。我搜索了类似的问题,但没找到。

我有一个方法DataTable instances = Microsoft.SqlServer.Smo.SmoApplication.EnumAvailableSqlServers(local: true); 的课程,后者又调用<LinearLayout android:id="@+id/new_formulas" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <EditText android:id="@+id/add_hint2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_weight="40" android:gravity="center_horizontal" android:hint="@string/add_hint" android:textSize="30dp" /> <EditText android:id="@+id/add_hint" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_toLeftOf="@id/add" android:layout_weight="40" android:hint="@string/add_hint" android:textSize="30dp" /> <Button android:id="@+id/add" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="20" android:layout_alignParentRight="true" android:text="@string/add" android:textSize="30dp" /> </LinearLayout>

我不想模仿method1()

我在嘲笑method2()的电话。我期待它会返回我想要的自定义对象(没有继续并调用method2)。但相反,它会继续并尝试拨打method1()

method2

我模拟了method1并返回任何对象(比如method2())。

我不希望调用class A { method1() { //do something. method2(); } } 。但是当我调试这个Junit时。它会调用new Integer(1)。因此失败了。

2 个答案:

答案 0 :(得分:0)

使用这样的语法时:

@Test public void yourTest() {
  A mockA = Mockito.mock(A.class, Mockito.CALLS_REAL_METHODS);
  when(mockA.method1()).thenReturn(Integer.valueOf(1));
}

那么Java将要做的第一件事是评估when(mockA.method1()),这需要调用mockA.method1()来获取传递给when的值。你没有注意到其他模拟,因为Mockito模拟返回了很好的默认值,但是对于间谍和CALLS_REAL_METHODS模拟,这是一个更大的问题。显然,这种语法不起作用。

相反,请使用以do开头的方法:

@Test public void yourTest() {
  A mockA = Mockito.mock(A.class, Mockito.CALLS_REAL_METHODS);
  doReturn(Integer.valueOf(1)).when(mockA).method1();
}

作为.when(mockA)的一部分,Mockito将返回一个没有行为的实例,因此对method1()的调用永远不会发生在实例上。 do语法也适用于void方法,这使得它比when(...).thenReturn(...)语法更灵活。一些开发人员主张始终使用doReturn;我更喜欢thenReturn,因为它更容易阅读,也可以为您进行返回类型检查。

作为旁注,除非您绝对需要全新的实例,否则请Integer.valueOf(1)优先于new Integer(1)。 Java保留小整数的缓存,如果您需要手动将int加入Integer,这比分配全新的引用要快。

答案 1 :(得分:-1)

通常,您可以模拟接口或抽象类,并提供抽象方法的实现。在您的情况下,您想要替换具体类的实际实现。这可以通过部分模拟来实现。

http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#16