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

在IntelliJ中用JUnit测试libGDX项目遇纹理加载问题求助

解决libGDX JUnit测试的GL空指针与文件找不到问题

一、核心问题分析

  1. GL20空指针:HeadlessApplication无真实GL上下文,但FirePuzzle.setUpPuzzle()中初始化了依赖GL的图形对象(如Image),导致GL相关调用失败。
  2. 文件找不到:测试运行时Gradle未将主程序资源目录复制到测试类路径,无法定位FirePuzzle/page.jpg。

二、分步解决方案

1. 解耦模型与视图(推荐)

模型类FirePuzzle不应直接依赖libGDX的Image(视图层类),应重构为:

  • 定义纯数据类Page,存储谜题逻辑所需的属性(如是否已烧毁、ID等)。
  • FirePuzzle仅操作Page数据,Image等图形对象交给视图层处理。
  • 测试时只需初始化Page数据,完全避开图形资源依赖,彻底解决GL空指针问题。

2. 临时修复(不重构代码的情况下)

(1)处理GL空指针

修改FirePuzzle添加测试专用初始化方法,跳过图形资源加载:

public class FirePuzzle {
    // ... 原有代码 ...
    // 新增测试用初始化方法
    public void setUpPuzzleForTest() {
        // 只初始化谜题逻辑数据,不创建Image、Texture等依赖GL的对象
        this.pages = new ArrayList<>();
        // 模拟添加Page数据,而非真实Image
        for (int i = 0; i < 5; i++) { // 假设原有逻辑是加载5页
            pages.add(new Page(i)); // 用自定义Page类代替Image
        }
        this.toBurn = pages.size();
    }
}

测试类中调用该方法替代setUpPuzzle():

@Before
public void setUp() throws Exception {
    // 初始化Headless环境,仅提供基础Gdx工具类(如Files)
    if (Gdx.files == null) {
        HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
        new HeadlessApplication(new ApplicationListener() {
            @Override public void create() {}
            @Override public void resize(int w, int h) {}
            @Override public void render() {}
            @Override public void pause() {}
            @Override public void resume() {}
            @Override public void dispose() {}
        }, config);
    }
    puzzle = FirePuzzle.getInstance();
    puzzle.setUpPuzzleForTest(); // 改用测试初始化方法
}

(2)解决文件找不到问题

在项目的build.gradle(core模块)中配置测试资源目录,将主程序资源复制到测试类路径:

sourceSets {
    test {
        resources.srcDirs = ["assets"] // 假设assets在core模块根目录下
        // 如果是多模块项目,路径可能是"../core/assets",根据实际结构调整
    }
}

同步Gradle配置后,测试时就能正确找到FirePuzzle/page.jpg。

3. 测试类优化

去掉不必要的Gioco实例初始化,避免触发多余的图形上下文加载:

public class FirePuzzleTest {
    private FirePuzzle puzzle;

    @Before
    public void setUp() throws Exception {
        // 初始化Headless环境(仅一次)
        if (Gdx.files == null) {
            HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
            new HeadlessApplication(new ApplicationListener() {}, config);
        }
        puzzle = FirePuzzle.getInstance();
        puzzle.setUpPuzzleForTest();
    }

    @After
    public void tearDown() throws Exception {
        puzzle.setNull();
        puzzle = null;
        // 清理Headless环境(可选)
        if (Gdx.app != null) {
            Gdx.app.exit();
        }
    }

    @Test
    public void burnPage() {
        int initialToBurn = puzzle.getToBurn();
        puzzle.burnPage(puzzle.getPages().get(0));
        assertEquals(initialToBurn - 1, puzzle.getToBurn());
    }

    @Test
    public void isSolved() {
        assertFalse(puzzle.isSolved());
        puzzle.getPages().forEach(puzzle::burnPage);
        assertTrue(puzzle.isSolved());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:37:02