对于相当多的人来说,用spring-boot和junit5编写单元测试是很困难的。我已经阅读了很多文章和一些junit5文档,但是没有找到任何有用的东西(或者我只是看不见)。
测试:
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = ScoreTestConfiguration.class)
@AutoConfigureMockMvc
public class ScoreControllerTest {
private static final String SCORE_ENDPOINT = "/scoring";
private static final ObjectMapper MAPPER = new ObjectMapper();
@Autowired
private MockMvc mockMvc;
@MockBean
private ScoreService mockScoreService;
@BeforeEach
public void setUp() {
ScoreResponseDto response = getScoreResponseDto();
when(mockScoreService.getScore(any(),any(),any(),any(),any(),any())).thenReturn(response);
}
@NotNull
private ScoreResponseDto getScoreResponseDto() {
ScoreResponseDto response = new ScoreResponseDto();
response.setCid("qwe13423qw");
response.setData(new ScoreResponseDto.ScoringData(0.78f));
return response;
}
@Test
public void sendValidRequest_getResponse_andOkStatus() throws Exception {
String request = SCORE_ENDPOINT +
"/380715346789" + //msisdn
"?score_formula=1234" +
"&clientId=5678" +
"&cid=543" +
"&stateType=" + StateType.ACTIVE.name() +
"&subscriberType=" + SubscriberType.POSTPAID.getValue();
String jsonResponse = MAPPER.writeValueAsString(getScoreResponseDto());
System.out.println("jsonResponse: " + jsonResponse);
mockMvc.perform(get(request))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(jsonResponse));
}}
配置(这是一个仅获取特定类的实验,但我失败了):
@Configuration
@ComponentScan(basePackages = "com.some.path.to.rest")
class ScoreTestConfiguration {
}当测试执行时,我假设,尽管我在@Configuration类中指定只加载其中的一部分,但全局上下文还是被启动了。
我的问题是如何控制和设置spring-boot和junit5测试的测试上下文的精确配置。
实际上,如果有人能提供一些关于组织本地测试框架的最佳实践的参考,我将非常感激。提前谢谢你!
发布于 2020-08-11 03:11:07
如果看不到更多的代码,就很难判断为什么测试配置不能满足您的需求。我已经创建了一个示例项目,其中包含几个与您的案例和其他案例类似的不同示例-您可以在here on GitHub中找到它。下面是你可以在那里找到的例子列表,并有简短的描述。
@SpringBootTest(classes = TestedController.class)
@AutoConfigureMockMvc
public class TestWithoutConfiguration {
@Test
void fails() {
}
}此测试失败,因为没有提供任何配置(除了控制器bean) -没有找到和注入任何bean。
@SpringBootTest(classes = {TestedController.class, TestConfiguration.class})
@AutoConfigureMockMvc
public class TestWithTestButWithoutMockBeanConfiguration {
@Test
void fails() {
}
}在这里,我们使用了一个测试配置,它为我们的控制器提供了一个服务bean,但是我们仍然缺少一个由service - MockedUtilInterface使用的bean (见下文)。
@SpringBootTest(classes = {TestedController.class, TestConfiguration.class})
@AutoConfigureMockMvc
public class TestWithTestConfiguration {
@Autowired
private MockMvc mockMvc;
@MockBean
private MockedUtilInterface mockedUtil;
@Test
void test() throws Exception {
when(mockedUtil.value())
.thenReturn(100);
mockMvc.perform(get("/test"))
.andExpect(content().string("100 - rest service from component scan value"));
}
}这个测试通过了-- TestConfiguration提供了服务bean,我们还创建了一个MockedUtilInterface bean作为模拟。模拟被注入到测试配置指向的服务中,而服务被注入到实际的控制器中。
@SpringBootTest
@AutoConfigureMockMvc
public class TestWithActualConfiguration {
@Autowired
private MockMvc mockMvc;
@Test
void test() throws Exception {
mockMvc.perform(get("/test"))
.andExpect(content().string("0 - not a test value"));
}
}这个测试也通过了,它使用了所有的实际配置,没有加载测试配置,所以所有的bean都是来自我们实际应用程序的bean(就像它是在容器中运行的一样)。
@SpringBootTest
@AutoConfigureMockMvc
public class TestWithInnerTestConfiguration {
@Configuration
@Import(TestedApplication.class)
static class InnerConfiguration {
@Bean
TestedServiceInterface service(MockedUtilInterface mockedUtil) {
return () -> mockedUtil.value() + " - inner value";
}
}
@Autowired
private MockMvc mockMvc;
@MockBean
private MockedUtilInterface mockedUtil;
@Test
void test() throws Exception {
when(mockedUtil.value())
.thenReturn(12345);
mockMvc.perform(get("/test"))
.andExpect(content().string("12345 - inner value"));
}
}下面是一个内部类配置的示例,它覆盖了一些beans,使用了一些实际的beans,还可以利用提供的@MockBeans。
Here您可以找到相当多的方法来为测试配置bean。
https://stackoverflow.com/questions/63342469
复制相似问题