2

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

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

我已经在各种类中“自动装配”了这个接口,我现在想用 Mockito 进行测试。

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

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

4

1 回答 1

0

我认为您想监视 Spring 为您的接口生成的实现?!到目前为止,这几乎是不可能实现的……但是,下面至少有以下替代方案。

假设我们有以下设置:

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

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

0)后来编辑:漫游时,我发现使用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)你可以创建你的接口模拟并在你的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;
    }
}
于 2016-02-29T23:51:54.300 回答