我正在Spring Boot应用程序上进行一些集成测试。
通常我用来开发的集成测试是关于应用程序域的,不涉及任何外部服务。 从那时起,我需要对使用数据库和SDK调用的外部服务的服务进行集成测试,我尝试过如下操作:
grep
令我困惑的是:我应该如何声明@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() {
...
}
}
属性?通常当我在单元测试中使用Mockito + PowerMock时,我通常会测试实现,而不是整个Service Interface + Spring Injection。但如果我只使用它的实现,我就不能使用myService
。
我遇到过这个问题的最佳做法吗?
答案 0 :(得分:1)
免责声明:我假设你所追求的是服务接口的端到端测试,由多个类支持。我假设(并希望)您没有一个类处理数据库和Web服务集成。
我认为不需要在这里使用PowerMock,它通常用于测试具有大量静态内容的遗留代码。如果您使用的是Spring引导,那么您的代码应具有不需要PowerMock的质量。
在编写端到端测试时,原则与每类单元测试相同,只是范围更广:
所以,在这里你应该找到一种机制来模拟与外部源通信的代码部分,比如Web服务客户端,数据库类(如果你没有为你的测试使用内存数据库(你应该) )。这通常是一个Spring配置,几乎与生产中使用的配置相同,但所有部件都被模拟了。然后,您只需@Inject
您需要与之通信的部分即可完成测试。
假设您对所有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
}
模拟也会被注入SomeClass