malkomalko
9/2/2012 - 3:46 PM

js testing cheatsheet

js testing cheatsheet

sinon / chai / mocha / js-tests

_____________________________________

#### chai

expect(subject).not.equal(expected)

  .a('string')
  .instanceof(Foo)

  .include(2)
  .contain('foo')
  .include.keys('foo')

  .not
  .ok
  .true
  .false
  .null
  .undefined
  .exist
  .empty
  .arguments

  .equal('hello')
  .eql({ foo: 'bar' })
  .deep.equal({ bar: 'baz' })
  
  .above(5)
  .length.above(2)
  .below(10)
  .length.below(4)
  .within(5,10)
  .length.within(2,4)
  .length(3)

  .property('foo')
  .deep.property('foo.bar.baz', 'quux')
  .deep.property('[1][2].tea', 'konacha')
  .property('foo’).a('string')
  .ownProperty('length')

  .match(/^foo/)
  .string('bar')

  .keys(['foo', 'bar'])
  .contain.keys('foo', 'bar')

  .throw(Error)
  .throw(/bad function/)
  .not.throw(new RangeError('Out of range.')

  .respondTo('bar')
  .satisfy(function(num) { return num > 0; })
  .closeTo(1, 0.5)

_____________________________________

#### sinon-chai

  .called
  .calledOnce
  .calledTwice
  .calledThrice
  .calledBefore(spy)
  .calledAfter(spy)
  .calledOn(context)
  .always.calledOn(context)
  .calledWith(args)
  .always.calledWith(args)
  .calledWithExactly(args)
  .always.calledWithExactly(args)
  .returned(val)
  .always.returned(val)
  .thrown(errorObjOrErrorTypeStringOrNothing)
  .always.thrown(errorObjOrErrorTypeStringOrNothing)

_____________________________________

#### chai-jquery

  .attr('foo')
  .attr('foo', 'bar')
  .attr('foo').match(/bar/)

  .css('background')
  .css('background-color', '#ffffff')
  .css('font-family').match(/sans-serif/)

  .data('foo')
  .data('foo', 'bar')
  .data('foo').match(/bar/)

  .class('foo')
  .id('#main')
  
  .html('<em>John Doe</em>')
  .text('John Doe')
  .value('2012')

  .visible
  .hidden
  .selected
  .checked
  .disabled
  .empty
  .exist

  .match('#foo')
  .be(':empty')

  .contain('text')
  .have('h1')

_____________________________________

#### sinon

## Test spies

  A test spy is a function that records arguments, return value,
  the value of this and exception thrown (if any) for all its calls.
  A test spy can be an anonymous function or it can wrap an existing function. 

  Creating spies: sinon.spy()

  var spy = sinon.spy()
  var spy = sinon.spy(myFunc)
  var spy = sinon.spy(object, "method")

  Spy API

  Spy objects are objects returned from sinon.spy().
  When spying on existing methods with sinon.spy(object, method),
  the following properties and methods are also available on object.method.

  spy.withArgs(arg1[, arg2, ...])

  spy.callCount
  spy.called
  spy.calledOnce
  spy.calledTwice
  spy.calledThrice

  spy.firstCall
  spy.secondCall
  spy.thirdCall
  spy.lastCall

  spy.calledBefore(anotherSpy)
  spy.calledAfter(anotherSpy)
  spy.calledOn(obj)
  spy.alwaysCalledOn(obj)
  spy.calledWith(arg1, arg2, ...)
  spy.alwaysCalledWith(arg1, arg2, ...)
  spy.calledWithExactly(arg1, arg2, ...)
  spy.alwaysCalledWithExactly(arg1, arg2, ...)
  spy.calledWithMatch(arg1, arg2, ...)
  spy.alwaysCalledWithMatch(arg1, arg2, ...)
  spy.calledWithNew()

  spy.notCalledWith(arg1, arg2, ...)
  spy.neverCalledWith(arg1, arg2, ...)
  spy.notCalledWithMatch(arg1, arg2, ...)
  spy.neverCalledWithMatch(arg1, arg2, ...)

  spy.threw()
  spy.threw("TypeError")
  spy.threw(obj)
  spy.alwaysThrew()
  spy.alwaysThrew("TypeError")
  spy.alwaysThrew(obj)

  spy.returned(obj)
  spy.alwaysReturned(obj)

  spy.thisValues
  spy.args
  spy.exceptions
  spy.returnValues
  spy.reset()
  spy.printf("format string", [arg1, arg2, ...])

  Individual spy calls

  var spyCall = spy.getCall(n)

  spyCall.calledOn(obj)
  spyCall.calledWith(arg1, arg2, ...)
  spyCall.calledWithExactly(arg1, arg2, ...)
  spyCall.calledWithMatch(arg1, arg2, ...)
  spyCall.notCalledWith(arg1, arg2, ...)
  spyCall.notCalledWithMatch(arg1, arg2, ...)

  spyCall.threw()
  spyCall.threw("TypeError")
  spyCall.threw(obj)
  spyCall.thisValue
  spyCall.args
  spyCall.exception
  spyCall.returnValue

## Test stubs

  Test stubs are functions (spies) with pre-programmed behavior.
  They support the full test spy API in addition to methods
  which can be used to alter the stub's behavior.

  As spies, stubs can be either anonymous, or wrap existing functions.
  When wrapping an existing function with a stub, the original function is not called.

  Stub API

  var stub = sinon.stub()
  var stub = sinon.stub(object, "method")
  var stub = sinon.stub(object, "method", func)
  var stub = sinon.stub(obj)

  stub.withArgs(arg1[, arg2, ...])
  stub.returns(obj)
  stub.returnsArg(index)

  stub.throws()
  stub.throws("TypeError")
  stub.throws(obj)

  stub.callsArg(index)
  stub.callsArgOn(index, context)
  stub.callsArgWith(index, arg1, arg2, ...)
  stub.callsArgOnWith(index, context, arg1, arg2, ...)

  stub.yields([arg1, arg2, ...])
  stub.yieldsOn(context, [arg1, arg2, ...])
  stub.yieldsTo(property[, arg1, arg2, ...])
  stub.yieldsToOn(property, context, [arg1, arg2, ...])
  spy.yield([arg1, arg2, ...])
  spy.yieldTo(callback, [arg1, arg2, ...])

  spy.callArg(argNum)
  spy.callArgWith(argNum, [arg1, arg2, ...])

## Mocks

  Mocks (and mock expectations) are fake methods (like spies)
  with pre-programmed behavior (like stubs) as well as
  pre-programmed expectations. A mock will fail your test if
  it is not used as expected.

  In general you should never have more than one mock
  (possibly with several expectations) in a single test.

  Expectations implement both the spies and stubs APIs.

  Mock API

  var mock = sinon.mock(obj)
  var expectation = mock.expects("method")
  mock.restore()
  mock.verify()

  Expectations

  All the expectation methods returns the expectation,
  meaning you can chain them.

  var expectation = sinon.expectation.create([methodName])
  var expectation = sinon.mock()

  expectation.atLeast(number)
  expectation.atMost(number)
  expectation.never()
  expectation.once()
  expectation.twice()
  expectation.thrice()
  expectation.exactly(number)
  expectation.withArgs(arg1, arg2, ...)
  expectation.withExactArgs(arg1, arg2, ...)
  expectation.on(obj)
  expecation.verify()

## Fake timers

  Fake timers is a synchronous implementation of setTimeout and friends
  that Sinon.JS can overwrite the global functions with to allow
  you to more easily test code using them.

  Fake timers API

  var clock = sinon.useFakeTimers()
  var clock = sinon.useFakeTimers(now)
  var clock = sinon.useFakeTimers([now, ]prop1, prop2, ...)
  clock.tick(ms)
  clock.restore()

_____________________________________