我有一个接口,它被注册为ServiceLocatorFactoryBean的一部分。这个接口的主要目的是充当工厂。单元使用ServiceLocatorFactoryBean测试一个类Autowired
我有“自动连接”这种接口在不同的班,我想现在测试的Mockito。
问题是Mockito不支持接口。如何在我正在测试的类中注入此接口的模拟。
我看到的唯一选择是使用SpringJunitRunner运行测试并提供具有bean配置的应用程序上下文。但是这太冗长了。
我有一个接口,它被注册为ServiceLocatorFactoryBean的一部分。这个接口的主要目的是充当工厂。单元使用ServiceLocatorFactoryBean测试一个类Autowired
我有“自动连接”这种接口在不同的班,我想现在测试的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)后来编辑:而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;
}
}
非常感谢您的意见@Morfic。很有用。 – manoj84
你是什么意思“Mockito不支持接口”?它完全:) 这是什么问题,例如: 'MyInterface myInterface = Mockito.mock(MyInterface.class);' 然后,您可以在创建您想要测试的类时进行设置。 – Kotse
在上述问题中的一个小错误,我试图在界面上进行@spy而不是模拟它。问题是我没有该接口的类的具体实现。如果你看看我上面发布的ServiceLocatorFactoryBean链接,文档提到你只是创建一个接口并让它成为接口,并且Spring提供接口的运行时实现。但是,间谍无法使用界面。这是来自Mockito.spy文档“但是Mockito不能实例化内部类,本地类,抽象类和接口。” – manoj84