使用HeadlessApplication单元测试调用ShaderProgram(如Stage)的Libgdx类

5

我正在尝试对我的libgdx应用程序的core包进行单元测试。

最佳方法是如何模拟ShaderProgram以便可以测试根类?

给定以下Libgdx测试运行程序的初始化:

init {
    val conf = HeadlessApplicationConfiguration()

    HeadlessApplication(this, conf)
    Gdx.gl = mock(GL20::class.java) 
    Gdx.gl20 = mock(GL20::class.java)
    Gdx.gl30 = mock(GL30::class.java)
    Gdx.graphics = mock(Graphics::class.java)
    `when`(Gdx.graphics.height).thenReturn(dimensions)
    `when`(Gdx.graphics.width).thenReturn(dimensions)
}

需要测试的函数位于一个 Application Listener 的子类中。

override fun create() {
    ...
    stage = Stage(ScreenViewport())
    ...
}

当Stage尝试编译着色器时,会在其中发生错误。

例如,在com.badlogic.gdx.graphics.g2d中的SpriteBatch.java文件中。

ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader);
if (shader.isCompiled() == false) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog());

shader.isCompiled() 看起来对于一个 HeadlessApplication 总是返回 false。

1个回答

2
由于目前还没有答案,我想分享一下我的当前知识/观点:
首先,我们需要问一个问题:我们是否可以一般地为GUI编写单元测试?如果您想要深入的答案,请参考this question。总之,您可以通过从帧缓冲计算哈希来对GUI进行单元测试,但一般建议尽可能将逻辑从GUI中移出,并且根本不要对GUI进行单元测试。除此之外,我的代码运行的大多数服务器都没有OpenGL硬件支持。假设我们不想麻烦使用软件渲染,单独对GUI进行单元测试也不是一个选项。
基于这些信息,我认为我的逻辑与GUI分离得不够好。但是,当进一步研究scene2d和很多围绕它的教程时,很明显scene2d希望您设计上将逻辑和GUI部分组合起来,有关参考请参见this question
假设您认为scene2d使得将逻辑和GUI分离变得非常困难,我们现在面临着op的问题,而常见的解决方案并不适用。
我认为,libGDX的所有元素都应该与HeadlessBackend完全兼容,但事实上它们并不兼容,这是libGDX的设计缺陷。到目前为止,我想到的唯一解决方法是,如果需要,模拟一个SpriteBatch,并将其传递给Stage:
val stage = Stage(myViewport, if (isHeadless) mock(SpriteBatch::class.java) else SpriteBatch())

虽然这样可以让您正常使用舞台,但我认为这不是一个真正的解决方案,因为您需要编写测试感知的代码。

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