使用类参数与实际对象参数

时间:2017-09-11 02:47:34

标签: testing mocking mockito

根据Mockito,这两者之间有什么区别 -

  

Mockito.when(serviceObject.myMethod(Customer.class))。thenThrow(新   的RuntimeException());

  

客户客户=新客户();   Mockito.when(serviceObject.myMethod(客户))。thenThrow(新   的RuntimeException());

如果两者都起到同样的作用,那么使用哪一个被认为是最佳实践?

2 个答案:

答案 0 :(得分:2)

使用泛型Customer类来匹配类型的第一个也可以写成:

  

Mockito.when(serviceObject.myMethod(Mockito.any(Customer.class)))thenThrow。(新   的RuntimeException());

如果是第二个,则传递将在存根中使用的实际对象。

用法:

如果您的方法myMethod根据Customer对象的状态抛出异常,那么您可以使用后一种方法,您可以在其中适当地设置Customer对象的状态。

但是如果你的方法myMethod不依赖于Customer对象来抛出异常而你需要它只是为了调用方法而将它作为参数传递,那么你可以采用前者方法

答案 1 :(得分:2)

您可能存在误解 - 当方法的签名允许参数时,方法规范myMethod(SomeClass.class)可能。像:

Whatever myMethod(Object o) {

或直接

Whatever myMethod(Class<X> clazz) {

换句话说:它是 Mockito对某个恰好属于类Class的参数做了特殊的事情!

因此,你的第一个选择不是“一般”的工作。示例:我将此代码放在单元测试中:

static class Inner {
    public int foo(String s) { return 5; }
}

@Test
public void testInner() {
    Inner mocked = mock(Inner.class);
    when(mocked.foo(Object.class)).thenReturn(4);
    System.out.println(mocked.foo(""));
}

猜猜是什么 - 上面的不是编译。因为foo()不允许使用 Class 参数。我们可以重写

static class Inner {
    public int foo(Object o) { return 5; }
}

@Test
public void testInner() {
    Inner mocked = mock(Inner.class);
    when(mocked.foo(Object.class)).thenReturn(4);
    System.out.println(mocked.foo(""));
}

现在以上编译 - 但在调用时打印0(零)。因为上述内容与mocked.foo(eq(Object.class))相同。换句话说:当你的方法签名允许传递一个Class实例然后传递一个类实例时,这就是mockito的简单模拟规范。在我的示例中:当传入的对象为Object.class时,将返回4。但传入的对象是“” - 因此Mockito默认启动并返回0。

我在这里得到另一个答案 - 我认为你混合了Mockito的旧版本要求你写下when(mocked.foo(any(ExpectedClass.class))) - 现在可以写成{{1} }。但是when(mocked.foo(any())) 不是 Mockito构造 - 它是一个简单的方法规范,它使特定对象“匹配” - 并且该特定对象碰巧是类Class的实例。