I am trying to run unit tests on my libgdx java program in android studio. I have success implementing classes that don't require the creation of a SpriteBatch, but for those classes that depend on it, such as classes that implement Screen, I am out of luck. I am using a headless application to run my tests.
The following class is what I am inheriting from to run my unit tests
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;
}
}
This is an example of a unit tests that doesn't give me errors:
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);
}
}
And this is an example of a unit test that gives me the shader error:
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;
}
}
And this is the error that I am getting:
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)
I have spent days trying to figure this one out and all I could find was someone asking the same question in a different forum with no answers to his question. Thanks in advance.
It looks like there is some error in your HealthBars class. Here's some advice:
If line 38 looks something like this: stage = new Stage(viewport, null) try to change it to stage = new Stage(viewport)
If this is not the problem, try creating a SpriteBatch and pass it into the Constructor of stage.
Also, when asking for advice, make sure you give appropiate code, i.e. classes that show up in your StackTrace
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With