java - 如何避免在 LIBGDX 中为单元测试编译着色器时出错?

标签 java libgdx game-engine

我正在尝试在 android studio 中对我的 libgdx java 程序运行单元测试。我成功地实现了不需要创建 SpriteBatch 的类,但是对于那些依赖于它的类,例如实现 Screen 的类,我运气不好。我正在使用 headless 应用程序来运行我的测试。

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

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 并将其传递到阶段的构造函数中。

此外,在寻求建议时,请确保您提供了适当的代码,即出现在您的 StackTrace 中的类

关于java - 如何避免在 LIBGDX 中为单元测试编译着色器时出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47361937/

相关文章:

java - 有一个 Controller 类可以促进其他类之间的通信吗?

java - Libgdx 更改窗口大小而不禁用桌面上的调整大小

java - 无法使用桌面运行桌面应用程序 :run LIBGDX

java - 测量正在运行的进程(不是我启动的进程)的磁盘 I/O

java - Android RecyclerView 无法呈现 SurfaceView

c# - 如何使用 C# 在 Unity 3D 中随机时间(相同位置)生成敌人?

3d - 使用深度缓冲使水边变得柔和

c++ - 在 Shutdown() 方法而不是析构函数中清理

java - 解析模式和同一模式中的导入

java - 有没有办法在 libGDX(Android 和 iOS 项目)中推送通知?