Java 如何避免为单元测试在LIBGDX中编译着色器时出错?
我试图在android studio中对我的libgdx java程序运行单元测试。我成功地实现了不需要创建SpriteBatch的类,但是对于那些依赖SpriteBatch的类,例如实现Screen的类,我运气不佳。我正在使用一个无头应用程序来运行我的测试 下面的类是我从中继承来运行单元测试的Java 如何避免为单元测试在LIBGDX中编译着色器时出错?,java,libgdx,game-engine,Java,Libgdx,Game Engine,我试图在android studio中对我的libgdx java程序运行单元测试。我成功地实现了不需要创建SpriteBatch的类,但是对于那些依赖SpriteBatch的类,例如实现Screen的类,我运气不佳。我正在使用一个无头应用程序来运行我的测试 下面的类是我从中继承来运行单元测试的 package supertest; import com.badlogic.gdx.Application; import com.badlogic.gdx.ApplicationListener;
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)
java.lang.IllegalArgumentException:批处理不能为空。
位于com.badlogic.gdx.scenes.scene2d.Stage.(Stage.java:109)
在com.dungeongame.scenes.HealthBars.(HealthBars.java:38)
在com.dungeongame.screens.BattleScreen.(BattleScreen.java:60)
在unittests.BattleScreenTest.setUp(BattleScreenTest.java:30)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:498)
位于org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:50)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
位于org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:47)
位于org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
位于org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
位于org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
位于org.junit.internal.runners.statements.runafter.evaluate(runafter.java:27)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:363)
位于org.junit.runners.Suite.runChild(Suite.java:128)
位于org.junit.runners.Suite.runChild(Suite.java:27)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:363)
位于org.junit.runner.JUnitCore.run(JUnitCore.java:137)
位于com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
位于com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
位于com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
位于com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
我花了好几天的时间试图弄明白这一点,我所能找到的只是有人在另一个论坛上问了同样的问题,而他的问题却没有答案。提前感谢。您的
HealthBars
类中似乎有一些错误。以下是一些建议:
stage=newstage(viewport,null)
尝试将其更改为stage=newstage(viewport)