如何使用 Mockito 模拟 Java 中的泛型方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31621342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 18:52:45  来源:igfitidea点击:

How to mock generic method in Java with Mockito?

javagenericsmockito

提问by Jon Erickson

How can we mock the IRouteHandlerRegistry? The error is Cannot resolve method thenReturn(IHandleRoute<TestRoute>)

我们怎么能嘲笑IRouteHandlerRegistry?错误是Cannot resolve method thenReturn(IHandleRoute<TestRoute>)

public interface RouteDefinition { }

public class TestRoute implements RouteDefinition { }

public interface IHandleRoute<TRoute extends RouteDefinition> {
    Route getHandlerFor(TRoute route);
}

public interface IRouteHandlerRegistry {
    <TRoute extends RouteDefinition> IHandleRoute<TRoute> getHandlerFor(TRoute route);
}

@Test
@SuppressWarnings("unchecked")
public void test() {
    // in my test
    RouteDefinition route = new TestRoute(); // TestRoute implements RouteDefinition
    IRouteHandlerRegistry registry = mock(IRouteHandlerRegistry.class);
    IHandleRoute<TestRoute> handler = mock(IHandleRoute.class);

    // Error: Cannot resolve method 'thenReturn(IHandleRoute<TestRoute>)'
    when(registry.getHandlerFor(route)).thenReturn(handler);
}

采纳答案by M Anouti

Even though TestRouteis a subtype of RouteDefinition, a IHandleRoute<TestRoute>is nota subtype of IHandleRoute<RouteDefinition>.

即使TestRoute是一个亚型RouteDefinition,一个IHandleRoute<TestRoute>没有的一个亚型IHandleRoute<RouteDefinition>

The whenmethod from Mockito returns an object of type OngoingStubbing<IHandleRoute<RouteDefinition>>. This is due to the compiler inferring the type parameter TRoutefrom the method

whenMockito 中的方法返回一个类型为 的对象OngoingStubbing<IHandleRoute<RouteDefinition>>。这是由于编译器TRoute从方法中推断出类型参数

<TRoute extends RouteDefinition> IHandleRoute<TRoute> getHandlerFor(TRoute route);

to be RouteDefinitionsince the argument passed to getHandlerForis declared of type RouteDefinition.

RouteDefinition因为传递给的参数getHandlerFor被声明为类型RouteDefinition

On the other hand, the thenReturnmethod is given an argument of type IHandleRoute<TestRoute>whereas it expects an IHandleRoute<RouteDefinition>, that is the type argument of the OngoingStubbingmentioned earlier. Hence the compiler error.

另一方面,该thenReturn方法被赋予一个类型参数,IHandleRoute<TestRoute>而它期望一个IHandleRoute<RouteDefinition>,即OngoingStubbing前面提到的类型参数。因此编译器错误。

To solve this, the simplest way is probably to change the declaration type of routeto be TestRoute:

要解决这个问题,最简单的方法可能是将声明类型更改routeTestRoute

TestRoute route = new TestRoute();

IRouteHandlerRegistry registry = mock(IRouteHandlerRegistry.class);
IHandleRoute<TestRoute> handler = mock(IHandleRoute.class);

when(registry.getHandlerFor(route)).thenReturn(handler);

回答by Fariba

If you write like this it will be ok:

如果你这样写就可以了:

Mockito.doReturn(handler).when(registry).getHandlerFor(Mockito.any(route.class))

回答by Gualtiero Testa

Mockito.whenargument should be a method not a mock.

Mockito.when参数应该是一种方法而不是模拟。

The correct statement is: when(registry.getHandlerFor (route)).thenReturn(handler)

正确的说法是: when(registry.getHandlerFor (route)).thenReturn(handler)