Unit Tests with HaxeFlixel

77 views
Skip to first unread message

Shaun Michael K. Stone

unread,
Aug 16, 2015, 6:30:25 AM8/16/15
to HaxeFlixel
Hi All,

Please let me know if I'm wrong, but is it safe to say that HaxeFlixel has made it near on impossible to mock objects for my unit tests. I want to create a wrapper class that contains all my game progress. So my first plan was to inject FlxSave as a dependency to my Progress class:

package storage;
import flixel.util.FlxSave;

/**
 * @author Shaun Stone (SMKS)
 */
class Progress
{
var savedData:FlxSave;

public function new(savedData:FlxSave) 
{
this.savedData = savedData;
}
}

When the game boots up I would then use this to store the score, move onto the next level, build up experience. Because it would be unit tested I would feel more comfortable that it works correctly, instead of these static calls I currently have (GameProgress) yuck!

package storage;
import flixel.FlxG;

/**
 * All saves and game progress should go through this class only!
 * 
 * @author Shaun Stone
 */
class GameProgress
{
private static inline var RANK_START:Int = 1;
public static function storeLevelProgress(levelId:Int):Void
{
GameProgress.setCurrentLevel(levelId);
if (FlxG.save.data.highestLevel == null) {
FlxG.save.data.highestLevel = levelId;
}
if (FlxG.save.data.highestLevel < levelId) {
FlxG.save.data.highestLevel = levelId;
}
}
public static function setCurrentLevel(levelId:Int) 
{
Reg.level = levelId;
FlxG.save.data.levelId = levelId;
}
public static function storeLevelScore(levelId:Int, score:Int):Void
{
Reg.scores[levelId] = score;
FlxG.save.data.scores = Reg.scores;
if (FlxG.save.data.highestScore == null) {
FlxG.save.data.highestScore = score;
}
if (FlxG.save.data.highestScore < score) {
FlxG.save.data.highestScore = score;
}
}
public static function getTotalScoreOfAllLevels():Int
{
var totalScore:Int = 0;
for (i in Reg.scores) {
totalScore += i;
}
return totalScore;
}
public static function getCurrentLevel():Int
{
if (GameProgress.levelProgressSaved()) {
return GameProgress.getSavedLevel();
}
return Reg.level;
}
public static function levelProgressSaved():Bool
{
if (FlxG.save.data.levelId != null) {
return true;
}
return false;
}
public static function getSavedLevel():Int
{
return FlxG.save.data.levelId;
}
public static function moveOnToNextLevel():Void
{
var nextLevel:Int = Reg.level + 1;
GameProgress.storeLevelProgress(nextLevel);
}
public static function getCurrentRank():Int
{
if (rankProgressSaved()) {
return FlxG.save.data.currentRank;
}
return GameProgress.RANK_START;
}
private static function rankProgressSaved() 
{
if (FlxG.save.data.currentRank != null) {
return true;
}
return false;
}
public static function getLatestScore():Int
{
var lastLevel:Int = GameProgress.getLevelJustCameFrom();
if (Reg.scores[lastLevel] == null) {
return 0;
}
return Reg.scores[lastLevel];
}
public static function getHighestScore():Int
{
if (FlxG.save.data.highestScore == null) {
return 0;
}
return FlxG.save.data.highestScore;
}
public static function getHighestLevel():Int
{
if (FlxG.save.data.highestLevel == null) {
return Reg.level;
}
return FlxG.save.data.highestLevel;
}
public static function getCurrentXP():Int
{
return Reg.experiencePoints;
}
public static function addXP(xp:Int):Void
{
Reg.experiencePoints += xp;
FlxG.save.data.experiencePoints = Reg.experiencePoints;
}
public static  function getLevelJustCameFrom():Int
{
if (GameProgress.getCurrentLevel() <= 1) {
return 1;
}
return GameProgress.getCurrentLevel() - 1;
}
}

I have managed to get munit up and working correctly for some decoupled classes I have done around calculations. But I want to persist storage and keep it contained within a single class for better maintenance.

package storage;

import flixel.util.FlxSave;
import massive.munit.util.Timer;
import massive.munit.Assert;
import massive.munit.async.AsyncFactory;
import storage.Progress;
import mockatoo.Mockatoo.*;

using mockatoo.Mockatoo;


class ProgressTest 
{
var progress:Progress;
var mockedSave:haxe.macro.Expr.ExprOf<T>;
public function new() 
{
}
@BeforeClass
public function beforeClass():Void
{
mockedSave = mock(FlxSave);
}
@AfterClass
public function afterClass():Void
{
}
@Before
public function setup():Void
{
   progress = new Progress(mockedSave);
}
@After
public function tearDown():Void
{
progress = null;
}
@Test
public function testHasSavedObjectMember():Void
{
}
}

I added the library to test.hxml and when I ran:

munit test -as3

Completely breaks my tests. Anyone else managed to get this up and running?

Thanks.

SruloArt

unread,
Aug 16, 2015, 7:32:05 AM8/16/15
to HaxeFlixel
* TLDR :) but maybe https://github.com/HaxeFlixel/flixel/tree/dev/tests may give you some more information about what(ever :D) you want to accomplish with HaxeFlixel + munit.

Shaun Michael K. Stone

unread,
Aug 16, 2015, 11:56:21 AM8/16/15
to HaxeFlixel
I am looking in master and there doesn't appear to be much code coverage. Or any cases of mocking.

SruloArt

unread,
Aug 18, 2015, 9:37:39 AM8/18/15
to HaxeFlixel
* I'm not sure why you would look there, I've linked to dev because that's where all of the information is found.

* There are several possible Haxe based libraries (other than munit) over at Github, some pretty advanced so it seems.
Reply all
Reply to author
Forward
0 new messages