2017-11-18 155 views
2

我想在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) 

我花了幾天試圖找出這一個和所有我能找到的是有人問同樣的問題在不同的論壇,沒有回答他的問題。提前致謝。

回答

0

看起來你的HealthBars類有一些錯誤。下面是一些建議:

  1. 如果線38看起來是這樣的:stage = new Stage(viewport, null)嘗試將其更改爲stage = new Stage(viewport)

  2. 如果這不是問題,嘗試創建一個SpriteBatch,並把它傳遞到舞臺的構造。

此外,尋求建議時,請確保您給appropiate代碼,即類,在你的堆棧跟蹤顯示