Testing 带有类参数和实际对象参数的Mockito mocking方法

Testing 带有类参数和实际对象参数的Mockito mocking方法,testing,mocking,mockito,Testing,Mocking,Mockito,根据Mockito的说法,这两者之间有什么区别- Mockito.when(serviceObject.myMethod(Customer.class)).thenthow(new RuntimeException()) 及 客户=新客户(); Mockito.when(serviceObject.myMethod(customer)).ThentThrow(新建 RuntimeException()) 如果两者都有相同的用途,那么使用哪一种被认为是最佳实践?第一种使用泛型客户类来匹配类型的方法

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

Mockito.when(serviceObject.myMethod(Customer.class)).thenthow(new RuntimeException())

客户=新客户(); Mockito.when(serviceObject.myMethod(customer)).ThentThrow(新建 RuntimeException())


如果两者都有相同的用途,那么使用哪一种被认为是最佳实践?

第一种使用泛型
客户
类来匹配类型的方法也可以写成:

Mockito.when(serviceObject.myMethod(Mockito.any(Customer.class))).thenthow(new RuntimeException())

在第二个示例中,您传递的是将在stubing中使用的实际对象

用法:

如果您的方法
myMethod
根据
Customer
对象的状态引发异常,那么您可以使用后一种方法,您可以适当地设置Customer对象的状态


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

您方面存在误解-该方法规范
myMethod(SomeClass.class)
仅当该方法的签名允许使用参数时才是可能的。比如:

Whatever myMethod(Object o) {
或者直接

Whatever myMethod(Class<X> clazz) {
猜猜看——上面的没有编译。因为
foo()
不允许类参数。我们可以改写成

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))
相同。换句话说:当方法签名允许传递一个类实例,然后传递一个类实例时,这就是mockito的简单模拟规范。在我的示例中:当传入对象是
object.class
,则返回4。但是传入的对象是“”-因此Mockito默认值生效并返回0


我同意这里的另一个答案-我认为你是混合了旧版本的Mockito要求你写下
when(mocked.foo(any(ExpectedClass.class))
-现在可以写为
when(mocked.foo(any())
。但是
when(mocked.foo(ExpectedClass.class))
不是一个Mockito构造-它是一个简单的方法规范,给出了一个特定的对象来“匹配”-并且该特定对象恰好是class类的一个实例。

你能告诉我
Mockito.any(Customer.class)的用途吗
正在服务,它与
Mockito.any()有何不同?因为我认为不同之处在于,事实并非如此。我认为做
Mockito.any(Customer.class)
意味着Customer.class的任何实例,但它不是它看起来的样子。要理解我在上面的评论中试图解释的内容,请检查这个问题-在这里你可以看到Mockito无法区分
Mockito.any(Customer.class)
Mockito.any(CustomerDetail.class)
。希望这个问题有意义。为了回答您有关用法的问题,
myMethod
正在使用
Customer
的实例,该实例正在我要测试的方法中实例化。因此,尽管这是基于客户的状态,但我对此无能为力。即使我在测试中创建了同一个客户实例,它也不会起作用,因为它的引用将不同于在测试方法中创建的客户实例的引用。我认为您的思路是正确的,所以我投了赞成票。但是我认为OP只是对他在那里做的事情有一个误解。因此,我写了自己的另一篇文章来澄清这一方面;-)我想我明白了。在我的例子中,我定义了参数类型为Object的
myMethod
method。因此,当我执行
serviceObject.myMethod(Customer.class)
serviceObject.myMethod(CustomerDetail.class)
时,Mockito并没有确认它。因此,在本例中,为了让Mockito确认它,我必须执行
serviceObject.myMethod(any())
。还有一个问题,在这种情况下,Mockito将如何处理
serviceObject.myMethod(any(Customer.class))
?因为我观察到莫基托也承认这一点。顺便说一句,非常感谢您的详细解释,这意味着很多!!你真的要把类对象传递给你的代码吗?如前所述:您的评论中包含的是期望Custom或CustomerDetails类对象的规范。不,方法的参数类型是object,但我传递的是Customer和CustomerDetail。Customer对象还是真正的Customer.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(""));
}