我有一个接口,它被注册为ServiceLocatorFactoryBean的一部分。此接口的主要目的是充当工厂。
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.html
我已经在各种类中"自动连线"了这个接口,我现在想用 Mockito 进行测试。
问题是Mockito不支持接口。如何在我正在测试的类中注入此接口的模拟。
我看到的唯一选择是使用 SpringJunitRunner 运行测试并提供具有 bean 配置的应用程序上下文。但这太啰嗦了。
我认为您想监视 Spring 为您的接口生成的实现吗?!到目前为止,这几乎不可能实现......但是,下面至少有以下替代方案。
假设我们有以下设置:
public interface MyService {
String doIt();
}
@Component
public static class ServiceConsumer {
@Autowired
private MyService service;
public String execute() {
return service.doIt();
}
}
0(后来的编辑:在漫游时,我发现可以使用Springockito注释监视甚至用模拟替换自动连线字段,而且也相当容易。
@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(您可以创建界面的模拟并将其自动注入Bean中的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;
}
}