2016-02-17 21 views
0

我有一个接口,它被注册为ServiceLocatorFactoryBean的一部分。这个接口的主要目的是充当工厂。单元使用ServiceLocatorFactoryBean测试一个类Autowired

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.html

我有“自动连接”这种接口在不同的班,我想现在测试的Mockito。

问题是Mockito不支持接口。如何在我正在测试的类中注入此接口的模拟。

我看到的唯一选择是使用SpringJunitRunner运行测试并提供具有bean配置的应用程序上下文。但是这太冗长了。

+0

你是什么意思“Mockito不支持接口”?它完全:) 这是什么问题,例如: 'MyInterface myInterface = Mockito.mock(MyInterface.class);' 然后,您可以在创建您想要测试的类时进行设置。 – Kotse

+0

在上述问题中的一个小错误,我试图在界面上进行@spy而不是模拟它。问题是我没有该接口的类的具体实现。如果你看看我上面发布的ServiceLocatorFactoryBean链接,文档提到你只是创建一个接口并让它成为接口,并且Spring提供接口的运行时实现。但是,间谍无法使用界面。这是来自Mockito.spy文档“但是Mockito不能实例化内部类,本地类,抽象类和接口。” – manoj84

回答

0

我认为您希望窥探Spring为您的界面生成的实现?到目前为止,这几乎无法实现......但是至少有以下几种替代方案。

假设我们有以下设置:

public interface MyService { 
    String doIt(); 
} 
@Component 
public static class ServiceConsumer { 
    @Autowired 
    private MyService service; 

    public String execute() { 
     return service.doIt(); 
    } 
} 

0)后来编辑:roaming around,我发现这是可能的间谍,甚至与更换自动装配Autowired场一个模拟,也很容易,使用Springockito-annotations

@RunWith(SpringJUnit4ClassRunner.class) 
@ComponentScan 
@ContextConfiguration(loader = SpringockitoAnnotatedContextLoader.class, classes = {SpringockitoConsumerTest.class}) 
public class SpringockitoConsumerTest { 

    @WrapWithSpy(beanName = "myService") 
    @Autowired 
    private MyService mockService; 

    @Autowired 
    private ServiceConsumer consumer; 

    @Test 
    public void shouldConsumeService() { 
     assertEquals("allDone", consumer.execute()); 
     verify(mockService).doIt(); 
    } 
} 

如果Springockito-annotations是出了问题,请参阅2项原建议如下


1)你可以只创建接口的模拟和自动注入它的Mockito在你的豆。这是最简单的解决方案(我可以在写作的时候想到的),但它并不保证@Autowired注解并没有在消费(或许可以增加一个专用的测试?)忘记:

public class AutoInjectMocksConsumerTest { 

    @Mock 
    private MyService serviceMock; 

    @InjectMocks 
    private ServiceConsumer consumer = new ServiceConsumer(); 

    @Before 
    public void initMocks() { 
     MockitoAnnotations.initMocks(this); 
     when(serviceMock.doIt()).thenReturn("allDone"); 
    } 

    @Test 
    public void shouldConsumeService() { 
     assertEquals("allDone", consumer.execute()); 
     verify(serviceMock).doIt(); 
    } 
} 

2)或者正如你所说的,你可以运行它与SpringJunitRunner尽可能地定义和实例化必要的Spring上下文,同时也提供自己的服务模拟。尽管人们可能会抱怨这个解决方案不是那么干净的,但我发现它足够优雅,并且它也验证@Autowired注释在消费者实现中没有被遗忘。

@RunWith(SpringJUnit4ClassRunner.class) 
@Configuration 
@ComponentScan 
@ContextConfiguration(classes = {SpringAutowiringConsumerTest.class}) 
public class SpringAutowiringConsumerTest { 

    @Autowired 
    private MyService mockService; 

    @Autowired 
    private ServiceConsumer consumer; 

    @Test 
    public void shouldConsumeService() { 
     assertEquals("allDone", consumer.execute()); 
     verify(mockService).doIt(); 
    } 

    @Bean 
    public MyService mockService() { 
     MyService serviceMock = mock(MyService.class); 
     when(serviceMock.doIt()).thenReturn("allDone"); 
     return serviceMock; 
    } 
} 
+0

非常感谢您的意见@Morfic。很有用。 – manoj84