使用 ServiceLocatorFactoryBean Autowired 对类进行单元测试



我有一个接口,它被注册为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;
    }
}

相关内容

  • 没有找到相关文章

最新更新