单元使用ServiceLocatorFactoryBean自动测试类

时间:2016-02-17 21:54:31

标签: spring junit mockito springmockito

我有一个Interface作为ServiceLocatorFactoryBean的一部分注册。该接口的主要目的是充当工厂。

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

我有" autowired"这个界面在各个类中,我想用Mockito测试。

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

我看到的唯一选择是使用SpringJunitRunner运行测试并提供具有bean配置的Application Context。但这太冗长了。

1 个答案:

答案 0 :(得分: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,我发现有可能间谍甚至用模拟替换自动装配的字段,并且相当容易,使用{{3} }}

@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;
    }
}