基于配置文件Spring Boot的自动实现

时间:2017-05-28 17:12:46

标签: java testing spring-boot spring-test

我正在使用Spring Boot开发REST API。问题是我有一个接口和两个实现,我只想用模拟实现进行测试。

Interface CRMService 

@Service
CRMServiceImpl

@Service
CRMServiceMock

实施:第一个是与后端的真正集成,第二个是用于测试目的的模拟,最好的方法是什么?基于活动配置文件的集成测试或测试?如果我需要根据个人资料自动提供服务,那么最佳做法是什么?

1 个答案:

答案 0 :(得分:1)

虽然我确定有例外,但通常它不应该是集成或单元测试(通常涉及模拟),但两者都是;看测试金字塔概念。

集成测试:只使用真实服务。如果它调用其他实时服务,那么考虑将URL注入Spring Boot属性,这些属性指向测试环境中的模拟服务器(Node.js或简单快捷的东西)。

单元测试:考虑使用像Mockito这样的测试框架。使用这个,您可以使用类似的模拟编写测试:

private CRMServiceImpl mockService = mock(CRMServiceImpl.class);

@Test
public void someTest() {
    when(mockService.someMethod(any(String.class), eq(5))).thenReturn("Hello from mock object.")
}

上面的例子粗略地转换为"当某个类调用&some ;; SomeMethod(String,int)'在您的服务上,返回指定的字符串"。

这种方式允许您在必要时仍然使用模拟,但避免必须维护整个模拟实现配置文件并避免自动连接的问题。

最后,如果您需要完全独立的实施,请考虑不要自动布线服务!相反,在配置类中使用@Bean注释,并通过构造函数将其注入需要它的类中。像这样:

@Configuration
public class ApplicationConfiguration {
    @Value{$"service.crm.inmem"} // Injected property
    private boolean inMem;

    @Bean
    CRMService getCRMService() {
        if (inMem) {
            return new CRMServiceMock();
        }
        return new CRMServiceImpl();
    }

    @Bean
    OtherService getOtherService() {
        // Inject CRMService interface into constructor instead of auto-wiring in OtherService.class
        return new OtherService(getCRMService());
    }
}

如果你想在内存存储和真正的数据库连接层之间切换,你可以使用^^的一个例子。

我个人建议像上面的例子那样进行依赖注入,即使没有多个实现,因为随着项目的增长,如果自动连线属性失败,很难找到确切的原因。另外明确显示依赖关系的来源可以帮助组织应用程序和可视化应用程序层次结构。