如何避免在LIBGDX中为单元测试编译着色器错误?

如何避免在LIBGDX中为单元测试编译着色器错误?

问题描述:

我想在android studio的libgdx java程序上运行单元测试。我已经成功实现了不需要创建SpriteBatch的类,但对于依赖它的类(例如实现Screen的类),我运气不佳。我正在使用无头应用程序来运行我的测试。如何避免在LIBGDX中为单元测试编译着色器错误?

下面的类是什么,我继承来运行我的单元测试

package supertest; 

import com.badlogic.gdx.Application; 
import com.badlogic.gdx.ApplicationListener; 
import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.Graphics; 
import com.badlogic.gdx.backends.headless.HeadlessApplication; 
import com.badlogic.gdx.graphics.GL20; 

import org.junit.AfterClass; 
import org.junit.BeforeClass; 
import org.mockito.Mockito; 

import static org.mockito.Mockito.when; 

public class GameTest { 
    // This is our "test" application 
    public static Application application; 


    // Before running any tests, initialize the application with the headless backend 
    @BeforeClass 
    public static void init() { 

     // Note that we don't need to implement any of the listener's methods 
     application = new HeadlessApplication(
       new ApplicationListener() { 
        @Override public void create() {} 

        @Override public void resize(int width, int height) {} 

        @Override public void render() {} 

        @Override public void pause() {} 

        @Override public void resume() {} 

        @Override public void dispose() {} 
       }); 

     // Use Mockito to mock the OpenGL methods since we are running headlessly 
     Gdx.gl20 = Mockito.mock(GL20.class); 
     Gdx.gl = Gdx.gl20; 

     // Mock the graphics class. 
     Gdx.graphics = Mockito.mock(Graphics.class); 
     when(Gdx.graphics.getWidth()).thenReturn(1000); 
     when(Gdx.graphics.getHeight()).thenReturn(1000); 
    } 

    // After we are done, clean up the application 
    @AfterClass 
    public static void cleanUp() { 
     // Exit the application first 
     application.exit(); 
     application = null; 
    } 
} 

这是一个单元测试,不给我错误的例子:

package unittests; 

import com.badlogic.gdx.audio.Music; 
import com.badlogic.gdx.maps.objects.RectangleMapObject; 
import com.badlogic.gdx.maps.tiled.TiledMap; 
import com.badlogic.gdx.maps.tiled.TmxMapLoader; 
import com.badlogic.gdx.math.Vector2; 
import com.badlogic.gdx.physics.box2d.Body; 
import com.badlogic.gdx.physics.box2d.BodyDef; 
import com.badlogic.gdx.physics.box2d.CircleShape; 
import com.badlogic.gdx.physics.box2d.FixtureDef; 
import com.badlogic.gdx.physics.box2d.PolygonShape; 
import com.badlogic.gdx.physics.box2d.World; 
import com.dungeongame.DungeonGame; 
import com.dungeongame.tools.Coin; 


import org.junit.Before; 
import org.junit.Test; 

import supertest.GameTest; 

import static org.junit.Assert.assertNotNull; 

/** 
* Created by armando on 11/17/17. 
*/ 

public class CoinTests extends GameTest { 
    private Body body; 
    private BodyDef bdef; 
    private TiledMap map; 
    private Music coinSound; 
    private World world; 
    private DungeonGame game; 

    @Before 
    public void setUp() { 
     game = new DungeonGame(); 
     game.init(); 
     world = new World(new Vector2(0f, 0f), false); 
     TmxMapLoader mapLoader = new TmxMapLoader(); 
     map = mapLoader.load("maps/sample-level-1/sample-level-1.tmx"); 
     coinSound = DungeonGame.assManager.get("audio/sound/coinsfx.wav", Music.class); 

     // Setup body1 
     bdef = new BodyDef(); 
     final FixtureDef fdef = new FixtureDef(); 
     bdef.type = BodyDef.BodyType.DynamicBody; 
     bdef.position.set(11f/100f, 10f); 
     bdef.fixedRotation = true; 
     body = world.createBody(bdef); 
     CircleShape shape = new CircleShape(); 
     shape.setRadius(10f/100f); 
     fdef.shape = shape; 
     body.createFixture(fdef).setUserData(this); 
    } 

    @Test 
    public void testSingleCoinCreation() { 
     Coin coin = new Coin(map.getLayers().get(2).getObjects().getByType(RectangleMapObject.class).get(0), world, map); 
     assertNotNull(coin); 
    } 
} 

这是给出着色器错误的单元测试的一个示例:

package unittests; 

import com.badlogic.gdx.graphics.g2d.SpriteBatch; 
import com.dungeongame.DungeonGame; 
import com.dungeongame.screens.BattleScreen; 
import com.dungeongame.tools.SaveSlot; 
import com.dungeongame.tools.ScreenSaver; 

import org.junit.Before; 
import org.junit.Test; 

import supertest.GameTest; 

import static org.mockito.Mockito.mock; 

/** 
* Created by sean on 11/17/17. 
*/ 

public class BattleScreenTest extends GameTest { 
    private DungeonGame game; 
    private SaveSlot save; 
    private BattleScreen testScreen; 

    @Before 
    public void setUp() { 
     game = new DungeonGame(); 
     game.init(); 
     save = new SaveSlot("testName", 1, 1, 1, new ScreenSaver()); 
     testScreen = new BattleScreen(game, save); 
    } 

    @Test 
    public void testBattleScreenCreation() { 
     assert testScreen != null; 
     assert testScreen.getSave().getName() == "testName"; 
    } 

    public void testContents() { 
     assert testScreen.player != null; 
     assert testScreen.fighter != null; 
     assert testScreen.enemyHealth > 0; 
     assert testScreen.getSave().getHealth() >= 0; 
     assert testScreen.controls != null; 
    } 
} 

而这是我得到的错误荷兰国际集团:

java.lang.IllegalArgumentException: batch cannot be null. 

    at com.badlogic.gdx.scenes.scene2d.Stage.<init>(Stage.java:109) 
    at com.dungeongame.scenes.HealthBars.<init>(HealthBars.java:38) 
    at com.dungeongame.screens.BattleScreen.<init>(BattleScreen.java:60) 
    at unittests.BattleScreenTest.setUp(BattleScreenTest.java:30) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.junit.runners.Suite.runChild(Suite.java:128) 
    at org.junit.runners.Suite.runChild(Suite.java:27) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84) 

我花了几天试图找出这一个和所有我能找到的是有人问同样的问题在不同的论坛,没有回答他的问题。提前致谢。

看起来你的HealthBars类有一些错误。下面是一些建议:

  1. 如果线38看起来是这样的:stage = new Stage(viewport, null)尝试将其更改为stage = new Stage(viewport)

  2. 如果这不是问题,尝试创建一个SpriteBatch,并把它传递到舞台的构造。

此外,寻求建议时,请确保您给appropiate代码,即类,在你的堆栈跟踪显示