使用 Spring 进行测试时如何不连接到服务?
How to not connect to service when testing with Spring?
我有一个使用 JHipster 构建的应用程序,其中包含多个测试。
我创建了一个简单的配置 class 来实例化一个连接到外部服务的 bean :
@Configuration
public class KurentoConfiguration {
@Bean(name = "kurentoClient")
public KurentoClient getKurentoClient(@Autowired ApplicationProperties applicationProperties) {
return KurentoClient.create(applicationProperties.getKurento().getWsUrl());
}
}
但是正如您所猜测的那样,此代码在测试期间崩溃,因为外部服务未启动但此代码在应用程序上下文加载期间仍然 运行。
所以我需要创建这个 bean 的 "stateless" 版本以便在测试期间使用。
这是一个由于我的配置而失败的测试的简单示例:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Face2FaceApp.class)
public class LogsResourceIntTest {
private MockMvc restLogsMockMvc;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
LogsResource logsResource = new LogsResource();
this.restLogsMockMvc = MockMvcBuilders
.standaloneSetup(logsResource)
.build();
}
@Test
public void getAllLogs()throws Exception {
restLogsMockMvc.perform(get("/management/logs"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE));
}
}
有什么解决方案可以让这个bean在单元测试期间不高度依赖外部服务?
您可以在测试中使用 MockBean 注释来替换现有的 bean :
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Face2FaceApp.class)
public class LogsResourceIntTest {
@MockBean
private KurentoClient kurentoClient;
private MockMvc restLogsMockMvc;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
LogsResource logsResource = new LogsResource();
this.restLogsMockMvc = MockMvcBuilders
.standaloneSetup(logsResource)
.build();
given(kurentoClient.someCall()).willReturn("mock");
}
....
}
感谢大家的帮助,我终于解决了这个问题:
- 我创建了一个 KurentoClient 接口并实现了一个调用 KurentoClient 方法的代理
- 我的"normal"@Bean kurentoClientreturns实现的代理
- 我写了一个@TestConfiguration (
UnitTestConfiguration
) 并添加了一个@Bean,其签名与上面装箱的那个相同,但是这个 returns mockito 的 mock(KurentoClient.class)
- 我创建了一个 class
TestBase
,每个测试 class 都会扩展并且
包含
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApp.class)
@ContextConfiguration(classes = UnitTestConfiguration.class)
public class TestBase {
}
我有一个使用 JHipster 构建的应用程序,其中包含多个测试。 我创建了一个简单的配置 class 来实例化一个连接到外部服务的 bean :
@Configuration
public class KurentoConfiguration {
@Bean(name = "kurentoClient")
public KurentoClient getKurentoClient(@Autowired ApplicationProperties applicationProperties) {
return KurentoClient.create(applicationProperties.getKurento().getWsUrl());
}
}
但是正如您所猜测的那样,此代码在测试期间崩溃,因为外部服务未启动但此代码在应用程序上下文加载期间仍然 运行。
所以我需要创建这个 bean 的 "stateless" 版本以便在测试期间使用。
这是一个由于我的配置而失败的测试的简单示例:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Face2FaceApp.class)
public class LogsResourceIntTest {
private MockMvc restLogsMockMvc;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
LogsResource logsResource = new LogsResource();
this.restLogsMockMvc = MockMvcBuilders
.standaloneSetup(logsResource)
.build();
}
@Test
public void getAllLogs()throws Exception {
restLogsMockMvc.perform(get("/management/logs"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE));
}
}
有什么解决方案可以让这个bean在单元测试期间不高度依赖外部服务?
您可以在测试中使用 MockBean 注释来替换现有的 bean :
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Face2FaceApp.class)
public class LogsResourceIntTest {
@MockBean
private KurentoClient kurentoClient;
private MockMvc restLogsMockMvc;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
LogsResource logsResource = new LogsResource();
this.restLogsMockMvc = MockMvcBuilders
.standaloneSetup(logsResource)
.build();
given(kurentoClient.someCall()).willReturn("mock");
}
....
}
感谢大家的帮助,我终于解决了这个问题:
- 我创建了一个 KurentoClient 接口并实现了一个调用 KurentoClient 方法的代理
- 我的"normal"@Bean kurentoClientreturns实现的代理
- 我写了一个@TestConfiguration (
UnitTestConfiguration
) 并添加了一个@Bean,其签名与上面装箱的那个相同,但是这个 returns mockito 的mock(KurentoClient.class)
- 我创建了一个 class
TestBase
,每个测试 class 都会扩展并且
包含
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApp.class)
@ContextConfiguration(classes = UnitTestConfiguration.class)
public class TestBase {
}