Java 与PowerMock和Spring Boot的集成测试

Java 与PowerMock和Spring Boot的集成测试,java,testing,spring-boot,mockito,powermock,Java,Testing,Spring Boot,Mockito,Powermock,我正在Spring Boot应用程序上进行一些集成测试 通常,我用来开发的集成测试是关于应用程序域的,不涉及任何外部服务。 由于这次我需要对一个同时使用数据库和SDK调用的外部服务的服务进行集成测试,所以我尝试了以下操作: @RunWith(PowerMockRunner::class) @SpringBootTest @PowerMockRunnerDelegate(SpringRunner::class) @PrepareForTest(McpProductService::class) c

我正在Spring Boot应用程序上进行一些集成测试

通常,我用来开发的集成测试是关于应用程序域的,不涉及任何外部服务。 由于这次我需要对一个同时使用数据库和SDK调用的外部服务的服务进行集成测试,所以我尝试了以下操作:

@RunWith(PowerMockRunner::class)
@SpringBootTest
@PowerMockRunnerDelegate(SpringRunner::class)
@PrepareForTest(McpProductService::class)
class MyServiceIntegration {

    @Mock
    private ExternalService externalService;

    @Autowired
    @InjectMocks
    private MyServiceImpl myService;

    @Test
    public void thisTestShouldWork() {
        ...
    }
}
让我困惑的是:我应该如何声明
myService
属性?通常,当我在单元测试中使用Mockito+PowerMock时,我通常测试实现,而不是整个服务接口+Spring注入。但是,如果我只使用它的实现,而不是接口,我就不能使用
@Autowired


对于我面临的这个问题,有什么最佳实践吗?

免责声明:我假设您所追求的是由多个类支持的服务接口的端到端测试。我假设(并希望)没有一个类同时处理数据库和Web服务集成

我不认为有必要在这里使用PowerMock,它通常用于测试带有大量静态内容的遗留代码。如果您使用的是Spring boot,那么代码的质量应该使PowerMock变得不必要

编写端到端测试时,原则与每类单元测试相同,只是范围更大:

  • 通过单元测试,您可以创建被测试类的实例,并模拟其所有外部依赖项(其他类)
  • 通过端到端测试,您可以创建受测模块的“实例”,并模拟其外部依赖关系
因此,在这里,您应该找到一种机制来模拟与外部源(如web服务客户端、数据库类)通信的代码部分(如果您不在测试中使用内存中的db(您应该这样做))。这将是一个典型的Spring配置,与生产中使用的配置几乎相同,但所述部件已模拟出来。然后,您只需注入完成测试所需的通信部件

假设对所有bean使用组件扫描和注释,则可以模拟端点类并使用概要文件:

此代码仅基于内存,可能无法用于复制粘贴,但希望您可以使用这些概念

@Profile("test")
@Configuration
public class TestConfiguration {
    @Bean
    @Primary
    public SomeWebserviceClient someWebserviceClient() {
        return mock(SomeWebserviceClient.class);
    }
}
生产代码:

@Service
public class SomeClass {
    @Inject 
    private SomeWebserviceClient client;
}
然后在测试中:

@RunWith(PowerMockRunner::class)
@SpringBootTest
@ActiveProfiles("test")
public class SomeTest {
    @Inject
    private SomeClass someClass;

    @Inject
    private SomeWebserviceClient client; //<< will inject mock
}
@RunWith(PowerMockRunner::class)
@春靴测试
@ActiveProfiles(“测试”)
公共类测试{
@注入
私人某类某类;
@注入

私人的WebServices客户机;//,你说的一切都是真的。我处于单元和E2E测试之间。我想实现的是你在答案的最后部分所解释的:使用我实现的服务的运行测试(使用Spring Current)。但是模仿将要到外部源的
@Service
s。你说“我假设(并希望)没有一个类同时处理数据库和Web服务集成”是什么意思?我有一个
@服务
和一些
@Autowired
服务,可以是内部的,也可以是外部的。我想我们在同一页上。实现这一点的实际机制有点取决于您的项目。我用一个常规的spring项目(不是spring boot)实现了这一点,然后我基本上有3个配置文件,一个用于测试(带有模拟),一个用于生产(具有实际端点),两种情况下都使用了一个commons。使用Spring boot,我猜你可以使用配置文件。我会更新我的答案,但不能保证它100%有效,因为我当时没有任何真正的代码示例。我会尝试从你的答案中得到我能得到的,并尝试找出解决方案,谢谢!更新了我的答案。让我困惑的是:为什么你说Powermock不好?我的意思是,我发现它在单元测试时非常有用。我不需要为不同的环境创建不同的配置,只需要为不同的环境创建不同的属性。我还可以运行不同的模拟行为,而无需使用Mockito创建方法和类。。。