Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implemented multiple expectations per mock

Also fixed callback arguments
  • Loading branch information...
commit 67c96d2cd6493f0c5de023b3efbde46c29ca7767 1 parent 4020805
@dhasenan authored
Showing with 42 additions and 18 deletions.
  1. +3 −1 README.md
  2. +28 −16 lib/maryjane.coffee
  3. +11 −1 test/maryjanetests.coffee
View
4 README.md
@@ -77,13 +77,15 @@ Here's what you can do with the mock options:
* `thenDo`: run a callback. See the section on callbacks below.
* `lax`: don't worry about arguments overmuch. If the caller supplied more arguments than you expected, that's just fine.
-You will soon be able to chain these together:
+You can even chain these together:
when(mock).frob(14)
.thenReturn('ya think?')
.thenThrow(new Error('Divide by Cucumber Exception'))
.thenDo(function() { assert.fail(); });
+Note that `lax` applies to the entire method call. If you want one response with lax matching and another with strict matching, you need to do that separately.
+
Okay, now you know how to set up a result. What about verifying that something has been called?
Just use the same process, but with `verify` rather than `when`:
View
44 lib/maryjane.coffee
@@ -120,42 +120,54 @@ addFieldOrMethod = (mock, type, field) ->
else if type.hasOwnProperty field
mock[field] = type[field]
+class MockOperation
+ constructor: (@retval, @exception, @cb) ->
+
+ execute: (mock, args) ->
+ if @cb?
+ return @cb.apply mock, args
+ else if @exception?
+ throw @exception
+ else
+ return @retval
+
class MockOptions
constructor: (@_mock, @_name, @_args) ->
# Use constructor assignment; otherwise the prototype fields
# leak and you end up setting all mocks ever to strict rather
# than just this one
@_strict = true
- @_returns = null
- @_ex = null
+ @_ops = []
@_count = 0
- @_userFunc = null
lax: ->
@_strict = false
return @
+
thenThrow: (ex) ->
- @_ex = ex
+ @_ops.push new MockOperation(null, ex)
return @
+
thenReturn: (value) ->
- @_returns = value
+ @_ops.push new MockOperation(value)
return @
+
thenDo: (fn) ->
- @_userFunc = fn
+ @_ops.push new MockOperation(null, null, fn)
return @
execute: (args) ->
+ op = null
+ if @_ops.length == 0
+ # Error?
+ return null
+
+ if @_count > @_ops.length
+ op = @_ops[@_ops.length - 1]
+ else
+ op = @_ops[@_count]
@_count++
- if (@_userFunc != null)
- #console.log 'calling user func'
- return @_userFunc(args)
- if (@_ex != null)
- #console.log 'throwing exception'
- throw @_ex
- if @_returns != null
- #console.log 'returning %s', @_returns.toString()
- return @_returns
- return null
+ op.execute @_mock, args
matches: (name, args) ->
#console.log 'checking %s vs expected %s', args, @_args
View
12 test/maryjanetests.coffee
@@ -53,7 +53,10 @@ exports['throw an exception'] = ->
exports['user callback'] = ->
mock = mj.mock(new UnderTest())
count = 0
- mj.when(mock).frob(1, 8).thenDo -> count++
+ mj.when(mock).frob(1, 8).thenDo (a, b) ->
+ assert.eql a, 1
+ assert.eql b, 8
+ count++
mock.frob 1, 8
assert.eql count, 1
@@ -82,3 +85,10 @@ exports['mock copies fields'] = ->
mock = mj.mock(h)
assert.eql mock.foo, h.foo
assert.eql mock.bar, h.bar
+
+exports['chained expectations'] = ->
+ mock = mj.mock(new UnderTest())
+ mj.when(mock).frob(1, 7).thenReturn(8).thenReturn(18).thenReturn('no thanks')
+ assert.eql mock.frob(1, 7), 8
+ assert.eql mock.frob(1, 7), 18
+ assert.eql mock.frob(1, 7), 'no thanks'
Please sign in to comment.
Something went wrong with that request. Please try again.