Project Outline
Class Index | File Index
«
JsMockito - Mockito port to JavaScript

Namespace JsMockito

Contents

  1. Let's verify some behaviour!
  2. How about some stubbing?
  3. Matching Arguments
  4. Verifying exact number of invocations / at least once / never
  5. Matching the context ('this')
  6. Making sure interactions never happened on a mock
  7. Finding redundant invocations

In the following examples object mocking is done with Array as this is well understood, although you probably wouldn't mock this in normal test development.

1. Let's verify some behaviour!

For an object:

//mock creation
var mockedArray = mock(Array);

//using mock object
mockedArray.push("one");
mockedArray.reverse();

//verification
verify(mockedArray).push("one");
verify(mockedArray).reverse();

For a function:

//mock creation
var mockedFunc = mockFunction();

//using mock function
mockedFunc('hello world');
mockedFunc.call(this, 'foobar');
mockedFunc.apply(this, [ 'barfoo' ]);

//verification
verify(mockedFunc)('hello world');
verify(mockedFunc)('foobar');
verify(mockedFunc)('barfoo');

Once created a mock will remember all interactions. Then you selectively verify whatever interactions you are interested in.

2. How about some stubbing?

For an object:

var mockedArray = mock(Array);

//stubbing
when(mockedArray).slice(0).thenReturn('f');
when(mockedArray).slice(1).thenThrow('An exception');
when(mockedArray).slice(2).then(function() { return 1+2 });

//the following returns "f"
assertThat(mockedArray.slice(0), equalTo('f'));

//the following throws exception 'An exception'
var ex = undefined;
try {
  mockedArray.slice(1);
} catch (e) {
  ex = e;
}
assertThat(ex, equalTo('An exception');

//the following invokes the stub method, which returns 3
assertThat(mockedArray.slice(2), equalTo(3));

//the following returns undefined as slice(999) was not stubbed
assertThat(mockedArray.slice(999), typeOf('undefined'));

//stubs can take multiple values to return in order (same for 'thenThrow' and 'then' as well)
when(mockedArray).pop().thenReturn('a', 'b', 'c');
assertThat(mockedArray.pop(), equalTo('a'));
assertThat(mockedArray.pop(), equalTo('b'));
assertThat(mockedArray.pop(), equalTo('c'));
assertThat(mockedArray.pop(), equalTo('c'));

//stubs can also be chained to return values in order
when(mockedArray).unshift().thenReturn('a').thenReturn('b').then(function() { return 'c' });
assertThat(mockedArray.unshift(), equalTo('a'));
assertThat(mockedArray.unshift(), equalTo('b'));
assertThat(mockedArray.unshift(), equalTo('c'));
assertThat(mockedArray.unshift(), equalTo('c'));

//stub matching can overlap, allowing for specific cases and defaults
when(mockedArray).slice(3).thenReturn('abcde');
when(mockedArray).slice(3, lessThan(0)).thenReturn('edcba');
assertThat(mockedArray.slice(3, -1), equalTo('edcba'));
assertThat(mockedArray.slice(3, 1), equalTo('abcde'));
assertThat(mockedArray.slice(3), equalTo('abcde'));

//can also verify a stubbed invocation, although this is usually redundant
verify(mockedArray).slice(0);

For a function:

var mockedFunc = mockFunction();

//stubbing
when(mockedFunc)(0).thenReturn('f');
when(mockedFunc)(1).thenThrow('An exception');
when(mockedFunc)(2).then(function() { return 1+2 });

//the following returns "f"
assertThat(mockedFunc(0), equalTo('f'))

//following throws exception 'An exception'
mockedFunc(1);
//the following throws exception 'An exception'
var ex = undefined;
try {
  mockedFunc(1);
} catch (e) {
  ex = e;
}
assertThat(ex, equalTo('An exception');

//the following invokes the stub method, which returns 3
assertThat(mockedFunc(2), equalTo(3));

//following returns undefined as mockedFunc(999) was not stubbed
assertThat(mockedFunc(999), typeOf('undefined'));

//stubs can take multiple values to return in order (same for 'thenThrow' and 'then' as well)
when(mockedFunc)(3).thenReturn('a', 'b', 'c');
assertThat(mockedFunc(3), equalTo('a'));
assertThat(mockedFunc(3), equalTo('b'));
assertThat(mockedFunc(3), equalTo('c'));
assertThat(mockedFunc(3), equalTo('c'));

//stubs can also be chained to return values in order
when(mockedFunc)(4).thenReturn('a').thenReturn('b').then(function() { return 'c' });
assertThat(mockedFunc(4), equalTo('a'));
assertThat(mockedFunc(4), equalTo('b'));
assertThat(mockedFunc(4), equalTo('c'));
assertThat(mockedFunc(4), equalTo('c'));

//stub matching can overlap, allowing for specific cases and defaults
when(mockedFunc)(5).thenReturn('abcde')
when(mockedFunc)(5, lessThan(0)).thenReturn('edcba')
assertThat(mockedFunc(5, -1), equalTo('edcba'))
assertThat(mockedFunc(5, 1), equalTo('abcde'))
assertThat(mockedFunc(5), equalTo('abcde'))

//can also verify a stubbed invocation, although this is usually redundant
verify(mockedFunc)(0);
  • By default mocks return undefined from all invocations;
  • Stubs can be overwritten;
  • Once stubbed, the method will always return the stubbed value regardless of how many times it is called;
  • Last stubbing is more important - when you stubbed the same method with the same (or overlapping) matchers many times.

3. Matching Arguments

JsMockito verifies arguments using JsHamcrest matchers.

var mockedArray = mock(Array);
var mockedFunc = mockFunction();

//stubbing using JsHamcrest
when(mockedArray).slice(lessThan(10)).thenReturn('f');
when(mockedFunc)(containsString('world')).thenReturn('foobar');

//following returns "f"
mockedArray.slice(5);

//following returns "foobar"
mockedFunc('hello world');

//you can also use matchers in verification
verify(mockedArray).slice(greaterThan(4));
verify(mockedFunc)(equalTo('hello world'));

//if not specified then the matcher is anything(), thus either of these
//will match an invocation with a single argument
verify(mockedFunc)();
verify(mockedFunc)(anything());
  • If the argument provided during verification/stubbing is not a JsHamcrest matcher, then 'equalTo(arg)' is used instead;
  • Where a function/method was invoked with an argument, but the stub or verification does not provide a matcher, then anything() is assumed;
  • The reverse, however, is not true - the anything() matcher will not match an argument that was never provided.

4. Verifying exact number of invocations / at least once / never

var mockedArray = mock(Array);
var mockedFunc = mockFunction();

mockedArray.slice(5);
mockedArray.slice(6);
mockedFunc('a');
mockedFunc('b');

//verification of multiple matching invocations
verify(mockedArray, times(2)).slice(anything());
verify(mockedFunc, times(2))(anything());

//the default is times(1), making these are equivalent
verify(mockedArray, times(1)).slice(5);
verify(mockedArray).slice(5);

5. Matching the context ('this')

Functions can be invoked with a specific context, using the 'call' or 'apply' methods. JsMockito mock functions (and mock object methods) will remember this context and verification/stubbing can match on it.

For a function:

var mockedFunc = mockFunction();
var context1 = {};
var context2 = {};

when(mockedFunc).call(equalTo(context2), anything()).thenReturn('hello');

mockedFunc.call(context1, 'foo');
//the following returns 'hello'
mockedFunc.apply(context2, [ 'bar' ]);

verify(mockedFunc).apply(context1, [ 'foo' ]);
verify(mockedFunc).call(context2, 'bar');

For object method invocations, the context is usually the object itself. But sometimes people do strange things, and you need to test it - so the same approach can be used for an object:

var mockedArray = mock(Array);
var otherContext = {};

when(mockedArray).slice.call(otherContext, 5).thenReturn('h');

//the following returns 'h'
mockedArray.slice.apply(otherContext, [ 5 ]);

verify(mockedArray).slice.call(equalTo(otherContext), 5);
  • For mock functions, the default context matcher is anything();
  • For mock object methods, the default context matcher is sameAs(mockObj).

6. Making sure interactions never happened on a mock

var mockOne = mock(Array);
var mockTwo = mock(Array);
var mockThree = mockFunction();

//only mockOne is interacted with
mockOne.push(5);

//verify a method was never called
verify(mockOne, never()).unshift('a');

//verify that other mocks were not interacted with
verifyZeroInteractions(mockTwo, mockThree);

7. Finding redundant invocations

var mockArray = mock(Array);

mockArray.push(5);
mockArray.push(8);

verify(mockArray).push(5);

// following verification will fail
verifyNoMoreInteractions(mockArray);

Defined in: jsmockito.js.

Field Summary
version Library version,
Verifiers Verifiers
Integration Verifiers
Method Summary
isMock(maybeMock) Test if a given variable is a mock
when(mock) Add a stub for a mock object method or mock function
verify(mock, verifier) Verify that a mock object method or mock function was invoked
verifyZeroInteractions(mock) Verify that no mock object methods or the mock function were ever invoked
verifyNoMoreInteractions(mock) Verify that no mock object method or mock function invocations remain unverified
spy(delegate) Create a mock that proxies a real function or object.
mockFunction(funcName, delegate) Create a mockable and stubbable anonymous function.
mock(Obj) Create a mockable and stubbable objects.
Field Detail
JsMockito.version
Library version,

            
JsMockito.Verifiers
Verifiers

            
JsMockito.Integration
Verifiers

            
Method Detail
JsMockito.isMock(maybeMock) : boolean
Test if a given variable is a mock

              
Parameters:
maybeMock An object
Returns:
{boolean} true if the variable is a mock
JsMockito.when(mock) : object or function
Add a stub for a mock object method or mock function

              
Parameters:
mock A mock object or mock anonymous function
Returns:
{object or function} A stub builder on which the method or function to be stubbed can be invoked
JsMockito.verify(mock, verifier) : object or function
Verify that a mock object method or mock function was invoked

              
Parameters:
mock A mock object or mock anonymous function
verifier Optional JsMockito.Verifier instance (default: JsMockito.Verifiers.once())
Returns:
{object or function} A verifier on which the method or function to be verified can be invoked
JsMockito.verifyZeroInteractions(mock)
Verify that no mock object methods or the mock function were ever invoked

              
Parameters:
mock A mock object or mock anonymous function (multiple accepted)
JsMockito.verifyNoMoreInteractions(mock)
Verify that no mock object method or mock function invocations remain unverified

              
Parameters:
mock A mock object or mock anonymous function (multiple accepted)
JsMockito.spy(delegate) : object or function
Create a mock that proxies a real function or object. All un-stubbed invocations will be passed through to the real implementation, but can still be verified.

              
Parameters:
{object or function} delegate A 'real' (concrete) object or function that the mock will delegate unstubbed invocations to
Returns:
{object or function} A mock object (as per mock) or mock function (as per mockFunction)
JsMockito.mockFunction(funcName, delegate) : function
Create a mockable and stubbable anonymous function.

Once created, the function can be invoked and will return undefined for any interactions that do not match stub declarations.

var mockFunc = JsMockito.mockFunction();
JsMockito.when(mockFunc).call(anything(), 1, 5).thenReturn(6);
mockFunc(1, 5); // result is 6
JsMockito.verify(mockFunc)(1, greaterThan(2));

              
Parameters:
funcName {string} The name of the mock function to use in messages (defaults to 'func')
delegate {function} The function to delegate unstubbed calls to (optional)
Returns:
{function} an anonymous function
JsMockito.mock(Obj) : object
Create a mockable and stubbable objects.

A mock is created with the constructor for an object as an argument. Once created, the mock object will have all the same methods as the source object which, when invoked, will return undefined by default.

Stub declarations may then be made for these methods to have them return useful values or perform actions when invoked.

MyObject = function() {
  this.add = function(a, b) { return a + b }
};

var mockObj = JsMockito.mock(MyObject);
mockObj.add(5, 4); // result is undefined

JsMockito.when(mockFunc).add(1, 2).thenReturn(6);
mockObj.add(1, 2); // result is 6

JsMockito.verify(mockObj).add(1, greaterThan(2)); // ok
JsMockito.verify(mockObj).add(1, equalTo(2)); // ok
JsMockito.verify(mockObj).add(1, 4); // will throw an exception

              
Parameters:
Obj {function} the constructor for the object to be mocked
Returns:
{object} a mock object
Documentation generated by JsDoc Toolkit 2.1.0 on Tue Aug 16 2011 16:26:01 GMT+0200 (CEST)