在无界面的LibGDX单元测试中创建纹理

9
我正在使用LibGDX headless backend运行jUnit测试,对于某些测试来说效果良好,但如果我尝试创建一个new Texture('myTexture.png');,则会出现NullPointerException。精确的错误信息如下:
java.lang.NullPointerException
    at com.badlogic.gdx.graphics.GLTexture.createGLHandle(GLTexture.java:207)

为了保持简单,我创建了一个只加载纹理的方法:
public class TextureLoader {
    public Texture load(){
        return new Texture("badlogic.jpg");
    }
}

那么,我的测试类是这样的:
public class TextureTest {

    @Before
    public void before(){
        final HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
        new HeadlessApplication(new ApplicationListener() {
            // Override necessary methods
            ...
        }, config);
    }

    @Test
    public void shouldCreateTexture() {
        TextureLoader loader = new TextureLoader();
        assertNotNull( loader.load() );
    }
}

这个方法在我的实际应用中可以正常工作,但在单元测试中不能。

我如何使用 HeadlessApplication 类来加载纹理?


libgdx的Texture类基本上是封装了一个OpenGL纹理句柄。无头后端没有OpenGL上下文(因此称为"无头")。在没有OpenGL上下文的情况下,无法创建OpenGL纹理句柄。 - Xoppa
好的,我明白了。我想这更像是一个普通的Java问题,但你知道在单元测试中处理这个问题的好方法吗?可以使用依赖注入,但是将每个纹理作为参数传递听起来有点混乱。 - twiz
2
目前,我通过使用lwjgl而非无头后端来解决了我的问题。这似乎是违反直觉的,因为我认为单元测试是无头后端存在的主要目的。我明白实际上没有无头OpenGL实现是毫无意义的,但是使用模拟API的方式不会更合理吗,以防止出现异常? - twiz
@twiz 我完全同意你的看法。我目前也在面临这个问题。我还没有完全解决它,你能否在你的问题中添加一个自我回答,附上你的JUnit测试代码? - Simon Forsberg
1个回答

8

模拟 Gdx.gl 帮助我解决了在纹理创建期间出现的空指针异常:

import static org.mockito.Mockito.mock;

...

Gdx.gl = mock(GL20.class);

我使用了GdxTestRunner与之一起使用,详情请参考https://bitbucket.org/TomGrill/libgdx-testing-sample

public GdxTestRunner(Class<?> klass) throws InitializationError {
    super(klass);
    HeadlessApplicationConfiguration conf = new HeadlessApplicationConfiguration();
    new HeadlessApplication(this, conf);
    Gdx.gl = mock(GL20.class); // my improvement
}

1
我完全放弃了LibGDX,实际上从未尝试过,但基于赞数,我将接受这个答案。 - twiz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接