Mocking (or using) Scene and other Phaser objects in unit tests

I’m creating a game where there are some places in the code base which I’d like to write some unit tests. One of these places is a logic where I create complex game objects from data definitions. The end result of the process is a Phaser game object, for example extended Image with custom properties.

Essentially I’d like to write tests to verify that a correct output entity is produced from certain input. However, I’m not quite sure how to handle creation of GameObject during tests since the require ´Scene´ in their constructor. How do you people have setup Phaser game or just few of its components for this kinds of tests?

In following Karma/Jasmine test (which is ran on browser) I only get error about Cannot read property 'queueDepthSort' which I suppose is because I didn’t init the Phaser framework from the beginning in my tests:

import { Scene } from 'phaser';
import { createEntity, createEntityFromTiledObject } from '../../core/EntityFactory';

describe('EntityFactory', () => {
  it('should have createEntity function', function() {
    expect(createEntity).not.toBe(undefined);
  });

  describe('entity creation from Tiled data', () => {
    it('should create an Image entity if given data with image key', function() {
      const createdEntity = createEntityFromTiledObject(
        {
          height: 51,
          name: 'mobilephone',
          properties: {
            atlasKey: 'kitchen_sprites',
            entityId: 'kitchen_phone',
            entityType: 'ClickableImage',
            imageKey: 'phone_active'
          },
          rotation: 0,
          type: 'entity',
          visible: true,
          width: 78,
          x: 651,
          y: 807
        },
        new Scene('testScene'),
        {}
      );
    });
  });
});

The first test runs fine since I don’t try to use Scene in it.

Note that I’m not trying to test my whole game this way. I just want to bootstrap just enough of the Phaser in my tests to run certain important pieces of code.

2 Likes

I use the before hook to create a game and stop the game loop and after to destroy the game: https://github.com/samme/phaser-component-health/blob/master/tests/tests.js

You can copy the scene to an outer variable in the postBoot callback, or possible other places:

scene = game.scene.getScene('default’);
3 Likes

Thanks for example! It looks a lot like I figured myself in the end except I didn’t know about the postBoot which made the solution a lot nicer!

Despite how I did it there, you probably don’t need both postBoot() and scene.init(), either one alone is enough.

Yeah, I only used the postBoot since I have a different method of creating a testing Scene which preloads some testing assets etc.