You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maven中Spring Boot测试非静态@BeforeAll方法报错排查

问题:Gradle迁移Maven后Spring Boot测试无法执行,@BeforeAll非静态方法报错

Gradle项目中已实现带有非静态@BeforeAll方法的Spring Boot测试,迁移至Maven项目后测试无法执行,报错InvalidTestClassError: Invalid test class。若改用JUnit4的@Test注解,会出现@BeforeAll方法不执行或提示BeforeAll must be static的问题。测试逻辑与Gradle项目完全一致,仅构建工具不同。


Gradle配置(build.gradle)

dependencies {
    testImplementation "org.springframework.boot:spring-boot-starter-test:${spring_boot_version}"
    implementation 'junit:junit:4.13.1'
    ....
}

tasks.named('test') {
    useJUnitPlatform()
}

测试类代码

抽象基类

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {DeardiaryApplication.class})
@WebAppConfiguration
public abstract class AbstractTest {
    protected MockMvc mvc;
    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    WebApplicationContext webApplicationContext;

    protected void setUp() {
        mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
...
}

测试子类

import org.junit.jupiter.api.*;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class DatabaseTest extends AbstractTest {

    @Autowired
    private ExerciseInterface exerciseService;

    @BeforeAll
    public void init() {
        setUp();
        exerciseDto = exerciseService.getByExerciseType(ExerciseTypeEnum.SNATCH).get(0);
    }

    @Test
....
}

Maven配置(pom.xml)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>${spring.boot.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.9.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.9.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring.boot.version}</version>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M8</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter-engine</artifactId>
                    <version>5.9.2</version>
                    <scope>test</scope>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

解决方案

核心问题

测试类混合了JUnit4(@RunWith)和JUnit5(@TestInstance、@BeforeAll)注解,导致Maven Surefire插件无法正确识别执行引擎。Gradle的useJUnitPlatform()可兼容混合场景,但Maven需明确配置并避免注解冲突。

步骤1:统一依赖,移除冗余配置

Spring Boot Starter Test已包含JUnit5核心依赖,无需单独引入junit-jupiter-api、junit-jupiter-engine,同时排除JUnit4依赖避免冲突:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>${spring.boot.version}</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

步骤2:替换JUnit4注解为JUnit5规范

将抽象基类的@RunWith(SpringJUnit4ClassRunner.class)替换为JUnit5的Spring扩展注解@ExtendWith(SpringExtension.class):

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = {DeardiaryApplication.class})
@WebAppConfiguration
public abstract class AbstractTest {
    // 原有代码不变
}

测试子类保留JUnit5的@TestInstance(TestInstance.Lifecycle.PER_CLASS)和@BeforeAll,确保@Test使用org.junit.jupiter.api.Test注解。

步骤3:简化Surefire插件配置

使用稳定版Surefire插件,无需额外指定JUnit5引擎依赖:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring.boot.version}</version>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.1.2</version>
        </plugin>
    </plugins>
</build>

验证

执行mvn test命令,测试类应正常执行,非静态@BeforeAll方法会在类初始化时执行一次。


内容的提问来源于stack exchange,提问作者hhrzc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:55:16