在IntelliJ中用JUnit测试libGDX项目遇纹理加载问题求助
解决libGDX JUnit测试的GL空指针与文件找不到问题
一、核心问题分析
- GL20空指针:HeadlessApplication无真实GL上下文,但
FirePuzzle.setUpPuzzle()中初始化了依赖GL的图形对象(如Image),导致GL相关调用失败。 - 文件找不到:测试运行时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
相关产品推荐
相关产品推荐

