Sunday, November 10, 2013

Requirejs test boilerplate

This time I'd like write about executing unit tests in a require js AMD environment.
You can find the complete code at github.
Given are the following two modules:
coffee/app/Playground.js
define(
    [
        'jquery'
    ], ->
        class Playground
            constructor: ->
                @$el = $ '.playground'
            add: (el)->
                @$el.append el
)

coffee/app/Player.js
define(
    [
        'Playground'
        'jquery'
    ], (Playground)->
        class Player
            constructor: ->
                @playground = new Playground

            scream: ->
                @$el.text 'waaaaaaaaaaaa'
                @

            render: ->
                @$el = $ '<div class="player"></div>'
                @playground.add @$el
                @
)

coffee/app/Zombie.js
define(
    [
        'Playground'
        'jquery'
    ], (Playground)->
        class Zombie
            constructor: ->
                @playground = new Playground

            moan: ->
                @$el.text 'uuuuuaaaarrr'
                @

            render: ->
                @$el = $ '<div class="zombie"></div>'
                @playground.add @$el
                @
)

As you can see player and zombie requires both playground and executing a function.
I want to test player and zombie independently without playground.
Therefor I'd like to mock the functions of playground.
Requirejs provides a map property to support annother version of a module:
requirejs.config({
    map: {
        'some/newmodule': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});
This means I would have to create two versions of a playground mock since I want to return different things with getCoordinates.
But I don't want to create different files of the same object every time I need a new behavior.
I've created a setup where every module can have its own mocks and you can change them dynamically without creating different version files.
Using my boilerplate from github I'm able to mock modules using the test configuration file:


define(
    [

    ], ->
        [
            path: 'Player', defineModules:
                'Playground': ->
                    define 'Playground', ->
                        class FakePlayground
                            add: -> console.log "mocked playground->add for Player has been called"

        ,
            path: 'Zombie', defineModules:
                'Playground': ->
                    define 'Playground', ->
                        class FakePlayground
                            add: -> console.log "mocked playground->add for Zombie has been called"
        ]
)

No comments:

Post a Comment