LaszloMock Library

LaszloMock Howto

  1. Create mocks
  2. Setup expectations
  3. Playback mocks
  4. Verify expectations

Mocking Objects

Creating

Mock objects are created from the prototype of another object and generate the same methods. This allows the object to mimic the same behavior of the actual object.

  
    var mock = new LaszloMock(this, ObjectToMock.prototype);
  

Expectations

The expectations of a mock are calls on a method that are expected to happen in the object that is being tested.

  
    mock.setValue(3);
    mock.getValue().andReturn(2);
  

Replaying

After the expectations of a mock are recorded, the mock needs to transition from recording to playback by calling replayMock.

  
    mock.setValue(3);
    mock.getValue().andReturn(2);

    mock.replayMock();

    //The following calls are treated as 'real' calls
    mock.setValue(3);
    mock.getValue();
  

Verification

After the expectations and playback of the mock are complete, the mock needs to verify that expected and actual calls match by calling verifyMock.

  
    mock.setValue(28)
    mock.replayMock();
    mock.setValue(28);
    mock.verifyMock();
  

Mocking Behavior

Returning Values

A return value can be specified in an expectation of a mock method call using andReturn.

  
    mock.getValue().andReturn(28);
    mock.getValue().andReturn([3, 6, 9]);
  

Stubbing Behavior

Stubbing the behavior of a method allows the method’s arguments to be matched in more specific ways.

  
    var capturedClosure = null;

    // Expectation that a function will be passed in.
    mock.getValue(function(){}).andStub(function(closure) {
      capturedClosure = closure;
    });

    // Expectation that the mock method will be 
    //  called within the closure.
    mock.doSomeAction();

    mock.replayMock();

    mock.getValue(function() { mock.doSomeAction() });
    capturedClosure();
  

Mock Events

Creating Mock Events

Mocking an object’s events allows asserting that and event was fired. LaszloMock provides mocking events on an object.

  
    LaszloMock.prototype.addEventMocks(
       m_fixture, "m_fixture", ["anEvent"]);

    m_fixture.anEvent.sendEvent('arguments');

    LaszloMock.prototype.replayMocks(m_fixture);

    m_fixture.anEvent.sendEvent('arguments');

    LaszloMock.prototype.verifyMocks(m_fixture);
  

Firing Mock Events

A mock can fire an event to assert that the object that is being tested is listening for the event and performs the appropriate actions when the event is fired.

  
    // Expected method to be called in event handler for 'anEvent'
    actionMock.performAction('some argument');

    actionMock.replayMock();

    mock.fireMockEvent("anEvent", 'some argument');
  

Creating Multiple Mocks Simultaneously

Mocking out objects individually poses problems when a particular test case has many mocks—as it requires many replays and verifies. Using the addMocks and addEventMocks methods only requires the use of one replay and one verify.

The addMocks method automatically creates attributes that are based on the key passed into the object literal. So there is no need to explicitly create the mock in setup.

  
    <method name="setUp"><![CDATA[
      LaszloMock.prototype.addMocks(this, {
        raceCar: RaceCar.prototype,
        truck: Truck.prototype
      });
      ]]>
    </method>

    <method name="tearDown"><![CDATA[
      LaszloMock.prototype.verifyMocks(this);
      ]]>
    </method>

    <method name="testSomeMethod"><![CDATA[
      m_raceCarMock.goFast();
      m_truckMock.goSlow();

      LaszloMock.prototype.replayMocks(this);

      m_fixture.someMethod();
      ]]>
    </method>
  

Mixing LaszloMock into a TestCase

LaszloMock provides a construct to ‘mix’ itself into an LzUnit testcase, which makes the library more straightforward and easy to use. Once LaszloMock is mixed in, the following method are exposed as methods on the test case:

  • addMocks
  • addEventMocks
  • addSimpleMock
  • addSimpleMocks
  • replayMocks
  • verifyMocks
  • resetMocks

Mixins in LaszloMock

  
    <method name="setUp"><![CDATA[
      LaszloMock.extend(this);

      setAttribute('m_fixture', new Fixture(this, addMocks({
        raceCar: RaceCar.prototype,
        truck: Truck.prototype
      })));          
      ]]>
    </method>

    <method name="tearDown"><![CDATA[
      verifyMocks();
      ]]>
    </method>

    <method name="testSomeMethod"><![CDATA[
      m_raceCarMock.goFast();
      m_truckMock.goSlow();

      replayMocks();

      m_fixture.someMethod();
      ]]>
    </method>

    <method name="testTirePunctured"><![CDATA[
      addSimpleMock("badTire", ["blow"]);
      addSimpleMocks("goodTire1", "goodTire2", "goodTire3")
      m_goodTire1Mock.addMockMethod("check");

      m_badTireMock.blow();
      m_goodTire1Mock.check();

      replayMocks();

      m_truckMock.fireMockEvent("punctured", {
        punctured: m_badTireMock,
        stillGood:
           [m_goodTire1Mock, m_goodTire2Mock, m_goodTire3Mock]
      });
      ]]>
    </method>
  

Limitations and Flaws

Argument Matching

  1. LaszloMock does not match array arguments deeply.
  2. LaszloMock does not match Laszlo object arguments except for instance equality.

Constraints

LaszloMock does not provide an argument constraint system, so its argument-matching abilities are limited compared to some mock object libraries. The andStub method should be used to assert array arguments, anonymous functions and Laszlo objects until a constraint system is added.

Edit