这里是 Java 17、Gradle 8.3 和 Spring Boot 3.2.4。我的
build.gradle
看起来像:
plugins {
id 'application'
id "io.freefair.lombok" version '6.4.0'
id 'org.springframework.boot' version '3.2.4'
id 'io.spring.dependency-management' version '1.1.4'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation (
'org.apache.commons:commons-lang3:3.12.0'
,'commons-io:commons-io:2.11.0'
,'org.projectlombok:lombok:1.18.16'
,"org.springframework.boot:spring-boot-starter"
,"org.springframework.boot:spring-boot-starter-actuator"
,"org.springframework.boot:spring-boot-starter-web"
,"org.springframework.boot:spring-boot-starter-data-jpa"
,"org.springframework.boot:spring-boot-starter-data-rest"
,"org.springframework.boot:spring-boot-starter-jdbc"
,"org.springframework.boot:spring-boot-starter-validation"
,"org.springframework.boot:spring-boot-starter-logging"
,"org.springframework.boot:spring-boot-starter-thymeleaf"
,"org.springframework.boot:spring-boot-starter-security"
,"org.springframework.boot:spring-boot-starter-oauth2-client"
,"org.springframework.boot:spring-boot-starter-mail"
,'mysql:mysql-connector-java:8.0.30'
,'org.liquibase:liquibase-core:4.26.0'
,'org.slf4j:log4j-over-slf4j:1.7.33'
)
testImplementation (
'org.springframework.boot:spring-boot-starter-test'
,'org.springframework.security:spring-security-test'
'org.junit.jupiter:junit-jupiter-api:5.8.1'
,'org.springframework.boot:spring-boot-starter-test'
,'org.springframework.security:spring-security-test'
,'com.h2database:h2:2.1.214'
,'org.mockito:mockito-core'
)
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
tasks.named('test') {
useJUnitPlatform()
}
bootJar {
archiveFileName = "myapp.jar"
}
java {
sourceCompatibility = '17'
}
我有一个基本单元测试课程:
@SpringBootTest
public abstract class BaseUnitTest {
@BeforeEach
public abstract void setupForEach();
protected UserEntity createMockUser() {
return Mockito.mock(UserEntity.class);
}
protected OrgEntity createMockOrganization() {
return Mockito.mock(OrgEntity.class);
}
// other test helper methods
}
还有测试课:
public class RegistrationServiceTest extends BaseUnitTest {
@MockBean
private UserService userService;
@MockBean
private OrgService orgService;
@Autowired
private RegistrationService registrationService;
@Override
public void setupForEach() {
}
@Test
public void inviteUser_whenInputIsGood_thenUserIsCreatedAndInviteIsSent() {
// setup
UserEntity newUser = createMockUser();
OrgEntity org = createMockOrganization();
when(userService.getByEmail(eq("some email"), anyBoolean())).thenReturn(null);
when(organizationService.getByRefId(anyString())).thenReturn(org);
// test
UserInvitationEntity result = registrationService.inviteUser(user);
// check
assertNotNull(result);
}
}
当我运行这个测试类时,出现以下异常:
java.lang.NoSuchMethodError: 'org.junit.jupiter.api.extension.ExecutableInvoker org.junit.jupiter.api.extension.ExtensionContext.getExecutableInvoker()'
at org.springframework.test.context.junit.jupiter.SpringExtension.registerMethodInvoker(SpringExtension.java:381)
at org.springframework.test.context.junit.jupiter.SpringExtension.beforeAll(SpringExtension.java:132)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$10(ClassBasedTestDescriptor.java:381)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:381)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:205)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:80)
<large stacktrack omitted for brevity>
Suppressed: java.lang.NoSuchMethodError: 'org.junit.jupiter.api.extension.ExecutableInvoker org.junit.jupiter.api.extension.ExtensionContext.getExecutableInvoker()'
at org.springframework.test.context.junit.jupiter.SpringExtension.registerMethodInvoker(SpringExtension.java:381)
at org.springframework.test.context.junit.jupiter.SpringExtension.afterAll(SpringExtension.java:143)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$16(ClassBasedTestDescriptor.java:447)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$17(ClassBasedTestDescriptor.java:447)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeAfterAllCallbacks(ClassBasedTestDescriptor.java:447)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:229)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:80)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:161)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:161)
... 48 more
不要担心我的测试类/方法的编码/实现,我很好奇为什么我会得到这个
java.lang.NoSuchMethodError
。我怀疑它的 Java、Spring Boot 和 JUnit 版本不兼容,但我不知道哪里出了问题。
问题是您包含了
junit-jupiter-engine
和 junit-jupiter-api
的显式依赖项。您包含版本 5.8.1,而我认为 Spring Boot 3.2 需要 5.10。
但是您不需要这些依赖项,因为它们已经作为
spring-boot-starter-test
的一部分引入。删除它们还可以防止您在将来的更新中获得不兼容的版本。
解决方案删除依赖项或至少版本号。但我会把它们一起删除。
dependencies {
implementation (
'org.apache.commons:commons-lang3:3.12.0'
,'commons-io:commons-io:2.11.0'
,'org.projectlombok:lombok'
,"org.springframework.boot:spring-boot-starter-actuator"
,"org.springframework.boot:spring-boot-starter-web"
,"org.springframework.boot:spring-boot-starter-data-jpa"
,"org.springframework.boot:spring-boot-starter-data-rest"
,"org.springframework.boot:spring-boot-starter-jdbc"
,"org.springframework.boot:spring-boot-starter-validation"
,"org.springframework.boot:spring-boot-starter-thymeleaf"
,"org.springframework.boot:spring-boot-starter-security"
,"org.springframework.boot:spring-boot-starter-oauth2-client"
,"org.springframework.boot:spring-boot-starter-mail"
,'com.mysql:mysql-connector-j'
,'org.liquibase:liquibase-core'
,'org.slf4j:log4j-over-slf4j'
)
testImplementation (
'org.springframework.boot:spring-boot-starter-test'
,'org.springframework.security:spring-security-test'
,'com.h2database:h2'
)
}
提示: Mockito 也已被
spring-boot-starter-test
拉入,并且 H2 版本也已被管理。
TIP2: Lombok 也由 Spring Boot 管理,也删除该版本以获得兼容版本。或者至少使用最新版本,因为旧版本无法与较新的 Java 版本很好地配合。 (或者完全放弃 Lombok,但这是另一个讨论;))。
TIP3:我将 MySQL 驱动程序更改为由 Spring Boot 管理的驱动程序(以及较新的坐标)。
TIP4: 您的 SLF4J 版本 1.7.33 不兼容,因为 Spring Boot 使用 2.0.x,删除该版本或完全删除依赖项,因为它已经自动引入。
提示5:您的
testImplemementation
(已删除)和常规implementation
中有重复的依赖项,您不需要spring-boot-starter
和spring-boot-starter-logging
,因为它们已被所有其他spring-boot-starter-*
依赖项拉入.