6.2.901.900
Mocks
This library includes functions and forms for working with
mocks. A mock is a "fake" function
used in place of the real thing during testing to simplify
the test and ensure only a single unit and not it’s complex
dependencies is being tested. Mocks are most useful for
testing code that calls side-effectful operations and IO.
source code: https://github.com/jackfirth/racket-mock
1 Basic Mock Construction
Predicate identifying mocks.
Returns a mocked version of
proc. The
mock may be used in place of
proc anywhere
and behaves just like
proc. When used
as a procedure, the returned
mock? forwards
the arguments it’s given to
proc and records
the argument list and the result
proc returned
in hidden mutable storage. This allows tests to verify
that a mock was called with the right arguments.
A prefab structure containg the arguments and result
values of a single call to a
mock?.
Returns a list of all the
mock-calls made
so far with
mock.
Returns
#t if
mock has ever been
called with arguments that are
equal? to
args, returns
#f otherwise.
In the list of arguments, supply by-position argument values
first, in order. Then supply keyword arguments, in any order.
Supply each keyword as a two-element list: (#:keyword value).
Returns the number of times mock has been
called.
2 RackUnit Checks for Mocks
A
rackunit check that fails if
mock
has never been called with
args.
Example: |
> (check-mock-called-with? '(some args) (void-mock)) | -------------------- | FAILURE | name: check-mock-called-with? | location: (#<path:/home/racket/build-pkgs/user/.racket/6.2.901.900/pkgs/jack-mock/mock/private/check.rkt> 10 4 138 23) | expression: (check-mock-called-with? args2 mock3) | params: ((some args) #<procedure:...t/private/kw.rkt:213:14>) |
| Check failure | -------------------- |
| |
|
A
rackunit check that fails if
mock
hasn’t been called exactly
n times.
Example: |
> (check-mock-num-calls 1 (void-mock)) | -------------------- | FAILURE | name: check-mock-num-calls | location: (#<path:/home/racket/build-pkgs/user/.racket/6.2.901.900/pkgs/jack-mock/mock/private/check.rkt> 11 4 189 20) | expression: (check-mock-num-calls expected-num-calls15 mock16) | params: (1 #<procedure:...t/private/kw.rkt:213:14>) |
| Check failure | -------------------- |
| |
|
3 Mock Constructors
Constructs a mock that acts like
void. Useful
for mocking procedures called only for their side effects
like
display.
Constructs a mock that acts like (const v).
Useful for making an IO reading operation return a
test-defined value without actually doing any IO.
Constructs a mock that accepts a single value and
compares it to each
case-v with
equal?,
then returns the corresponding
case-result for
the first
case-v that is
equal? to
the given value. If no
case-v matches, an
exception is thrown.
Examples: |
> (define foo-bar-mock (case-mock 'foo 1 'bar 2)) | | > (foo-bar-mock 'foo) | 1 | > (foo-bar-mock 'bar) | 2 | > (foo-bar-mock 'unexpected) | v: contract violation | expected: (or/c) | given: 'unexpected |
|
4 Mocking Out Functions for Testing
Mocks by themselves provide useful low-level building
blocks, but often to use them a function needs to be
implemented twice - once using mocks for the purpose
of testing, and once using real functions to provide
actual functionality. These syntactic forms provide
shorthands for defining both implementations at once.
(define/mock header ([mock-id mock-expr] ...) body ...)
|
|
header | | = | | id | | | | | | (header arg ...) |
|
|
|
Like
define, but also
defines a mocked
version of
id in a
test submodule. The
mocked version uses the same
body ... as the
unmocked version, but each
mock-id is shadowed
and bound to
mock-expr in the test submodule and
used in place of
mock-id in
body ....
Each
mock-id is left alone in the normal implementation.
Examples: |
| | > (require 'm) | sent to real displayln | sent to real displayln | #f |
| | > (require (submod 'm test)) | sent to mock displayln | sent to mock displayln | #f |
| |
|
(define/mock-as header (mock-clause ...) body ...)
|
|
header | | = | | id | | | | | | (header arg ...) | | | | | | mock-clause | | = | | [mock-id mock-value-id mock-expr] |
|
|
|
Like
define/mock, but in the test submodule each
mock-expr is bound as
mock-value-id instead.
This prevents shadowing in the submodule so that both the
mocked and unmocked versions are available, and allows the
mock value to be named something other than
mock-id.
Examples: |
| eval:2:0: displayln-mock: unbound identifier in module | context...: | #(165746 module) #(165747 module m 0) #(167188 module) | #(167189 module (m test) 0) #(167225 local) #(167226 | intdef) | other binding...: | #<module-path-index:()> | #(165746 module) #(165747 module m 0) #(165783 macro) | #(167188 module) | #(167189 module (m test) 0) | in: displayln-mock | > (require 'm) | require: unknown module | module name: #<resolved-module-path:'m> | > (require (submod 'm test)) | require: unknown module | module name: #<resolved-module-path:(submod 'm test)> |
|