繁体   English   中英

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

[英]How to mock generic method in Java with Mockito?

我们如何模拟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);
}

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

来自Mockito的when方法返回类型为OngoingStubbing<IHandleRoute<RouteDefinition>> 这是由于编译器从方法中推断出类型参数TRoute

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

RouteDefinition过去了的说法getHandlerFor声明类型的RouteDefinition

另一方面, thenReturn方法给出了IHandleRoute<TestRoute>类型的参数,而它期望IHandleRoute<RouteDefinition> ,这是前面提到的OngoingStubbing的类型参数。 因此编译错误。

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

TestRoute route = new TestRoute();

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

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

如果你这样写,那就没关系了:

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

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

正确的语句是: when(registry.getHandlerFor (route)).thenReturn(handler)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM