我的环境是 Spring Boot 3.0.2、Gradle 和 Java 17。我实现了一个包含 300 多个单元和集成测试的应用程序。
经过 200 次测试后,我的套件变得不稳定。如果我从 intellij 启动测试,它们都会正常工作。如果我从 gradle 命令一项一项地运行测试,它们也能正常工作。但如果我一起运行所有测试,有些测试会随机失败。
错误是无法加载某些mockbean。
如果我将此配置放在 build.gradle 中,那么所有测试都会顺利进行,但需要很长时间。
tasks.named('test') {
forkEvery = 1
useJUnitPlatform()
}
如果我采用其他配置,则其他测试将失败
tasks.named('test') {
maxParallelForks = Runtime.runtime.availableProcessors()
useJUnitPlatform()
}
会不会是内存问题?并行进程或类似的东西?很奇怪,事实并没有给我任何信心。
例如测试类。
package ...
import ...
@SpringBootTest
@ActiveProfiles("test")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class OfferCreateTest {
@Autowired
PropertyCreate propertyCreate;
@Autowired
OfferCreate offerCreate;
@MockBean
ObHttpClient obHttpClient;
@MockBean
RoomtypeFind roomtypeFind;
@MockBean
RateplanFind rateplanFind;
@MockBean
PropertyChannelFind propertyChannelFind;
private Long propertyId;
@BeforeAll
void setup(){
propertyId = createProperty();
}
private Long createProperty(){
PropertyCreateDto propertyCreateDto = PropertyCreateDtoMother.randomWithFullData();
return propertyCreate.create(propertyCreateDto).getResult().get("id");
}
@Test
void create_offer(){
OfferCreateDto offerCreateDto = OfferCreateDtoMother.random();
Long offerId = offerCreate.create(propertyId, offerCreateDto).getResult().get("id");
assertTrue(offerId >= 100000L);
}
@Test
void create_offer_on_non_existing_property(){
OfferCreateDto offerCreateDto = OfferCreateDtoMother.random();
assertThrows(Exception.class, () -> offerCreate.create(ContentGenerator.customIdLower(), offerCreateDto));
}
}
非常感谢,
就我而言,问题是由于 MockStatic 使用不当造成的。 如果使用MockStatic并且不释放资源,则当另一个类时会使用模拟对象。 因此,根据测试的顺序,它们要么成功,要么失败。
上一个代码
mockStatic(UserFactory.class))
.when(() -> UserFactory.of(anyString(), anyMap()))
.thenReturn(User.builder().build());
when(userRepositoryOAuth2UserHandler.apply(any())).thenReturn(User.builder().build());
when(jwtProvider.createAccessToken(any())).thenReturn("accessToken");
when(jwtProvider.createRefreshToken(any())).thenReturn("refreshToken");
oAuth2LoginSuccessHandler.onAuthenticationSuccess(request, response,
createAuthentication());
assertAll(
() -> assertThat(response.getStatus()).isEqualTo(SC_OK),
() -> assertThat(response.getContentType()).isEqualTo(APPLICATION_JSON_VALUE),
() -> verify(objectMapper).writeValue(eq(response.getOutputStream()),
any(LoginSuccessResponse.class))
);
修改代码
try (MockedStatic<UserFactory> mockUserFactory = mockStatic(UserFactory.class)) {
mockUserFactory
.when(() -> UserFactory.of(anyString(), anyMap()))
.thenReturn(User.builder().build());
when(userRepositoryOAuth2UserHandler.apply(any())).thenReturn(User.builder().build());
when(jwtProvider.createAccessToken(any())).thenReturn("accessToken");
when(jwtProvider.createRefreshToken(any())).thenReturn("refreshToken");
oAuth2LoginSuccessHandler.onAuthenticationSuccess(request, response,
createAuthentication());
assertAll(
() -> assertThat(response.getStatus()).isEqualTo(SC_OK),
() -> assertThat(response.getContentType()).isEqualTo(APPLICATION_JSON_VALUE),
() -> verify(objectMapper).writeValue(eq(response.getOutputStream()),
any(LoginSuccessResponse.class))
);
}
通过进行这些修改,我能够解决问题。