我正在尝试对我的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。
由于到目前为止还没有答案,我想分享我目前的知识/意见:
首先,我们需要问一个问题:我们甚至可以为GUI编写单元测试吗?如果你想要一个深入的答案,看看这个问题。总而言之:您可以通过从帧缓冲区计算哈希来对 GUI 进行单元测试,但一般建议是将尽可能多的逻辑移出 GUI,并且根本不对 GUI 进行单元测试。除此之外,我和大多数运行代码的服务器都没有对OpenGL的硬件支持。假设我们不想打扰软件渲染,则无法对GUI本身进行单元测试。
基于这些信息,我认为我的逻辑与我的GUI分离得不够好。但是,当进一步研究 scene2d 和围绕它的许多教程时,很明显 scene2d 希望您通过设计将代码的逻辑和 GUI 部分结合起来,请参阅此问题以供参考。
假设你同意 scene2d 使得很难将你的逻辑和 GUI 分开的观点,我们现在面临着操作的问题,而常见的解决方案不适用。
在我看来,libGDX的所有元素都应该与HeadlessBackend完全兼容,它们不是libGDX的设计缺陷。到目前为止,我想出的唯一解决方法是在需要时模拟SpriteBatch并将其传递给舞台:
val stage = Stage(myViewport, if (isHeadless) mock(SpriteBatch::class.java) else SpriteBatch())
虽然这允许您正常使用您的舞台,但我不认为它是一个真正的解决方案,因为您需要编写代码测试感知。