Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid Error compiling shader in LIBGDX for a unit test?

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.

like image 945
mandy1339 Avatar asked Feb 13 '26 09:02

mandy1339


1 Answers

It looks like there is some error in your HealthBars class. Here's some advice:

  1. If line 38 looks something like this: stage = new Stage(viewport, null) try to change it to stage = new Stage(viewport)

  2. 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

like image 93
Skrelp Avatar answered Feb 15 '26 23:02

Skrelp