java - 基于配置文件 Spring Boot 的 Autowiring 实现

标签 java testing spring-boot spring-test

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

Interface CRMService 

@Service
CRMServiceImpl

@Service
CRMServiceMock

实现:第一个是与后端的真正集成,第二个是用于测试目的的模拟,什么是最好的方法?集成测试或基于 Activity 配置文件的测试?如果我需要根据配置文件 Autowiring 服务,最佳做法是什么?

最佳答案

虽然我确定有异常(exception),但通常不应该是集成或单元测试(通常涉及模拟),而是两者兼而有之;请参阅测试金字塔概念。

集成测试:只使用真正的服务。如果它调用其他实时服务,则考虑将 URL 作为 Spring Boot 属性注入(inject),这些属性指向测试环境中的模拟服务器(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.")
}

上面的示例大致翻译为“当某个类在您的服务上调用‘someMethod(String, int)’时,返回指定的字符串”。

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

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

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

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

我个人建议像上面的示例一样进行依赖注入(inject),即使没有多个实现也是如此,因为随着项目的增长,如果自动连接的属性失败,则很难找到确切原因。此外,明确显示依赖项的来源有助于组织应用程序和可视化应用程序层次结构。

关于java - 基于配置文件 Spring Boot 的 Autowiring 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44229962/

相关文章:

java - 将列表添加到 ArrayList<String> 并显示在 ListView 上

java - java中如何获取类中的字段列表?

testing - 使用 Eclipse 进行 junit 测试

image - 在 QTP 等自动化工具上测试应用程序时如何通过验证码

java - Spring Boot - REST 和 SOAP 组合

java - 创建 HTML 文档

java - 如何访问 Swing JTextField/JPasswordField 内的值?

java - 如何从数据库获取 spring-logback 的路径

testing - 在沙盒模式下,应用内购买交易失败并出现 SKErrorPaymentCancelled

gradle - 来自 gradle 的 org.gradle.api.internal.LocationAwareException