On this page:
2.1 Core Mock API
mock?
mock
mock-name
current-mock-name
current-mock-calls
current-mock-num-calls
mock-reset!
with-mock-behavior
mock-call
mock-call?
mock-call-args
mock-call-name
mock-call-results
mock-calls
mock-called-with?
mock-num-calls
exn:  fail:  unexpected-arguments
2.2 Behavior Construction Utilities
const/  kw
void/  kw
const-raise
const-raise-exn
const-series
2.3 Mock Call Histories
call-history
call-history?
call-history-record!
call-history-calls
call-history-count
call-history-reset!
2.4 Opaque Values
define-opaque
2.5 Mocking Dependencies
define/  mock
with-mocks
2.6 Stub Implementations
stub
exn:  fail:  not-implemented
7.7

2 The Mock Reference

This document describes the complete API of the mock library. For a gentler introduction and use cases, see The Mock Guide.

    2.1 Core Mock API

    2.2 Behavior Construction Utilities

    2.3 Mock Call Histories

    2.4 Opaque Values

    2.5 Mocking Dependencies

    2.6 Stub Implementations

2.1 Core Mock API

procedure

(mock? v)  boolean?

  v : any/c
Predicate identifying mocks.

Examples:
> (mock? (mock #:behavior void))

#t

> (mock? void)

#f

procedure

(mock [#:behavior behavior-proc    
  #:name name    
  #:external-histories histories])  mock?
  behavior-proc : procedure? = #f
  name : symbol? = #f
  histories : (listof call-history?) = (list)
Returns a mock that records arguments its called with and results it returns. When called as a procedure, the mock consults its current behavior, a procedure initalized to behavior-proc that defines how the mock responds to arguments, and stores a mock-call containing the give arguments and the result values of the behavior. The mock’s list of calls can be queried with mock-calls and erased with mock-reset!. The mock’s behavior can be temporarily altered using with-mock-behavior. If behavior is not provided, the mock by default raises an exn:fail:unexpected-arguments with a message in terms of name.

Examples:
> (define quotient/remainder-mock
    (mock #:behavior quotient/remainder))
> (quotient/remainder-mock 10 3)

3

1

> (mock? quotient/remainder-mock)

#t

> (define uncallable-mock (mock #:name 'uncallable-mock))
> (uncallable-mock 1 2 3 #:foo 'bar #:bar "blah")

uncallable-mock: unexpectedly called with arguments

  positional:

   1

   2

   3

  keyword:

   #:bar: "blah"

   #:foo: 'bar

In addition to recording calls itself, the returned mock records calls in each of the given histories. The call histories in histories are not reset with call-history-reset! when the returned mock is reset with mock-reset!. External histories can be shared between mocks, allowing tests to verify the order in which a set of mocks is called.

Examples:
> (define h (call-history))
> (define m1 (mock #:name 'm1 #:behavior void #:external-histories (list h)))
> (define m2 (mock #:name 'm2 #:behavior void #:external-histories (list h)))
> (m1 'foo)
> (m2 'bar)
> (m1 'baz)
> (call-history-calls h)

(list

 (mock-call 'm1 (arguments 'foo) '(#<void>))

 (mock-call 'm2 (arguments 'bar) '(#<void>))

 (mock-call 'm1 (arguments 'baz) '(#<void>)))

procedure

(mock-name a-mock)  (or/c symbol? #f)

  a-mock : mock?
Returns the name of a-mock if present.

Examples:
> (mock-name (mock #:name 'foo))

'foo

> (mock-name (mock))

#f

Added in version 2.0 of package mock.

procedure

(current-mock-name)  (or/c symbol? #f)

Returns the name of the current mock being called. This is for use in behaviors, for example to raise an error with a message in terms of the mock currently being called.

Examples:
> (define (log-call . vs)
    (printf "Mock ~a called with ~a args"
            (or (current-mock-name) 'anonymous)
            (length vs)))
> (define log-mock (mock #:name 'log-mock #:behavior log-call))
> (log-mock 1 2 3)

Mock log-mock called with 3 args

> (log-mock 'foo 'bar)

Mock log-mock called with 2 args

If called outside the context of a mock behavior call, raises exn:fail.

Example:
> (current-mock-name)

current-mock-name: can't be called outside mock behavior

If the mock being called is anonymous, returns #f.

Examples:
> (define log-mock-anon (mock #:behavior log-call))
> (log-mock-anon 1 2 3)

Mock anonymous called with 3 args

> (log-mock-anon 'foo 'bar)

Mock anonymous called with 2 args

Added in version 1.1 of package mock.

Returns a list of all the previous calls of the current mock being called. This is for use in behaviors, for example to implement a behavior that returns a set of all keywords its ever been called with.

Examples:
> (define keyword-set
    (make-keyword-procedure
     (λ (kws _)
       (define (call-kws call)
         (hash-keys (arguments-keyword (mock-call-args call))))
       (define prev-kws
         (append-map call-kws (current-mock-calls)))
       (apply set (append kws prev-kws)))))
> (define kw-set-mock (mock #:behavior keyword-set))
> (kw-set-mock #:foo 'bar)

(set '#:foo)

> (kw-set-mock #:baz "blah")

(set '#:foo '#:baz)

If called outside the context of a mock behavior call, raises exn:fail.

Example:
> (current-mock-calls)

current-mock-calls: can't be called outside mock behavior

Added in version 1.2 of package mock.

Returns the number of times the current mock being called has already been called. This is for use in beahviors, for example to log the number of times this mock has been called.

Examples:
> (define (log-count)
    (printf "Mock called ~a times previously" (current-mock-num-calls)))
> (define count-mock (mock #:behavior log-count))
> (count-mock)

Mock called 0 times previously

> (count-mock)

Mock called 1 times previously

> (mock-reset! count-mock)
> (count-mock)

Mock called 0 times previously

If called outside the context of a mock behavior call, raises exn:fail.

Example:
> (current-mock-num-calls)

current-mock-num-calls: can't be called outside mock

behavior

Added in version 1.3 of package mock.

procedure

(mock-reset! m)  void?

  m : mock?
Erases the history of mock-call values in m.

Examples:
> (define void-mock (mock #:behavior void))
> (void-mock 'foo)
> (mock-num-calls void-mock)

1

> (mock-reset! void-mock)
> (mock-num-calls void-mock)

0

syntax

(with-mock-behavior ([mock-expr behavior-expr] ...) body ...)

 
  mock-expr : mock?
  behavior-expr : procedure?
Evaluates each mock-expr and behavior-expr which must be a mock and a procedure? respectively, then alters the mock’s behavior in the dynamic extent of body ... to the given behavior procedure. This allows the same mock to behave differently between calls, which is useful for testing a procedure defined with define/mock in different ways for different tests.

Examples:
> (define num-mock (mock #:behavior add1))
> (num-mock 10)

11

> (with-mock-behavior ([num-mock sub1])
    (num-mock 10))

9

> (num-mock 10)

11

> (mock-calls num-mock)

(list

 (mock-call #f (arguments 10) '(11))

 (mock-call #f (arguments 10) '(9))

 (mock-call #f (arguments 10) '(11)))

procedure

(mock-call [#:name name    
  #:args args    
  #:results results])  mock-call?
  name : (or/c symbol? #f) = #f
  args : arguments? = (arguments)
  results : list? = (list)

procedure

(mock-call? v)  boolean?

  v : any/c

procedure

(mock-call-args call)  arguments?

  call : mock-call?

procedure

(mock-call-name call)  (or/c symbol? #f)

  call : mock-call?

procedure

(mock-call-results call)  list?

  call : mock-call?
Constructor, predicate, and accessors of a structure containing the arguments and result values of a single call to a mock with name name.

Example:
> (mock-call #:name 'magnificent-mock
             #:args (arguments 1 2 #:foo 'bar)
             #:results (list 'value 'another-value))

(mock-call 'magnificent-mock (arguments 1 2 #:foo 'bar) '(value another-value))

Changed in version 2.0 of package mock: Changed from a plain struct to a keyword-based constructor and added a name field.

procedure

(mock-calls m)  (listof mock-call?)

  m : mock?
Returns a list of all the calls made so far with m in order, as a list of mock-call? structs.

Examples:
> (define void-mock (mock #:behavior void))
> (void-mock 10 3)
> (void-mock 'foo 'bar 'baz)
> (mock-calls void-mock)

(list

 (mock-call #f (arguments 10 3) '(#<void>))

 (mock-call #f (arguments 'foo 'bar 'baz) '(#<void>)))

procedure

(mock-called-with? m args)  boolean?

  m : mock?
  args : arguments?
Returns #t if m has ever been called with args, returns #f otherwise.

Examples:
> (define ~a-mock (mock #:behavior ~a))
> (~a-mock 0 #:width 3 #:align 'left)

"0  "

> (mock-called-with? ~a-mock (arguments 0 #:align 'left #:width 3))

#t

procedure

(mock-num-calls m)  exact-nonnegative-integer?

  m : mock?
Returns the number of times m has been called.

Examples:
> (define void-mock (mock #:behavior void))
> (void-mock 10 3)
> (void-mock 'foo 'bar 'baz)
> (mock-num-calls void-mock)

2

struct

(struct exn:fail:unexpected-arguments exn:fail (args)
    #:transparent)
  args : arguments?
An exception type used by mocks that don’t expect to be called at all.

2.2 Behavior Construction Utilities

procedure

(const/kw v)  procedure?

  v : any/c
Like const, but the returned procedure accepts keyword arguments.

Examples:
> ((const/kw 'a) 1)

'a

> ((const/kw 'a) #:foo 2)

'a

Added in version 1.5 of package mock.

Like void, but accepts keyword arguments.

Examples:
> (void/kw 1)
> (void/kw #:foo 2)

Added in version 1.5 of package mock.

procedure

(const-raise v)  procedure?

  v : any/c
Like const/kw, but instead of returning v the returned procedure always raises v whenever it’s called.

Examples:
> ((const-raise 'a) 1)

uncaught exception: a

> ((const-raise 'a) #:foo 2)

uncaught exception: a

Added in version 1.5 of package mock.

procedure

(const-raise-exn [#:message msg    
  #:constructor ctor])  procedure?
  msg : string? = "failure"
  ctor : (-> string? continuation-mark-set? any/c)
   = make-exn:fail
Like const-raise, but designed for raising exceptions. More precisely, the returned procedure raises the result of (ctor msg (current-continuation-marks)) whenever it’s called.

Examples:
> ((const-raise-exn) 1)

failure

> ((const-raise-exn #:message "some other failure") #:foo 2)

some other failure

> (define (exn/custom-message msg marks)
    (make-exn:fail (format "custom: ~a" msg) marks))
> ((const-raise-exn #:constructor exn/custom-message) #:bar 3)

custom: failure

Added in version 1.5 of package mock.

procedure

(const-series v ... [#:reset? reset?])  procedure?

  v : any/c
  reset? : boolean? = #f
Returns a procedure that ignores positional and keyword arguments and returns the first v when called for the first time, the second v when called for the second time, the third on the third time, and so on until no more vs remain. Then, calls cause the procedure to fail with an exception if reset? is false. Otherwise, the pattern resets.

Examples:
> (define ab-proc (const-series 'a 'b))
> (ab-proc 1)

'a

> (ab-proc #:foo 2)

'b

> (ab-proc #:bar 3)

raise-arguments-error: contract violation

  expected: string?

  given: 'num-calls

  argument position: 3rd

  other arguments...:

   'const-series

   "called more times than number of arguments"

   2

> (define ab-proc (const-series 'a 'b #:repeat? #t))
> (ab-proc)

'a

> (ab-proc)

'b

> (ab-proc)

'a

Added in version 1.5 of package mock.

2.3 Mock Call Histories

procedure

(call-history)  call-history?

Constructs a fresh mock call history value. Every mock has an associated call history, although external call histories can be shared between mocks. Call histories store a log of mock-call values in the order the calls were made.

procedure

(call-history? v)  boolean?

  v : any/c
Returns true when v is a call-history value, and false otherwise.

procedure

(call-history-record! history call)  void?

  history : call-history?
  call : mock-call?
Saves call in history as the most recent mock call.

procedure

(call-history-calls history)  (listof mock-call?)

  history : call-history?
Returns a list of all calls recorded in history with call-history-record!. The list contains calls in order of least recent to most recent.

Examples:
> (define history (call-history))
> (call-history-record! history
                        (mock-call #:name 'foo
                                   #:args (arguments 1 2 3)
                                   #:results (list 'foo)))
> (call-history-record! history
                        (mock-call #:name 'bar
                                   #:args (arguments 10 20 30)
                                   #:results (list 'bar)))
> (call-history-calls history)

(list

 (mock-call 'foo (arguments 1 2 3) '(foo))

 (mock-call 'bar (arguments 10 20 30) '(bar)))

procedure

(call-history-count history)  (listof mock-call?)

  history : call-history?
Returns the number of calls recorded in history.

Examples:
> (define history (call-history))
> (call-history-count history)

0

> (call-history-record! history (mock-call))
> (call-history-count history)

1

procedure

(call-history-reset! history)  void?

  history : call-history?
Erases all calls from history, in a similar manner to mock-reset!.

Examples:
> (define history (call-history))
> (call-history-record! history (mock-call))
> (call-history-reset! history)
> (call-history-calls history)

'()

2.4 Opaque Values

Often libraries work with values whose representations are unknown to clients, values which can only be constructed via those libraries. For example, a database library may define a database connection value and a database-connection? predicate, and only allow construction of connections via a database-connect! procedure. This is powerful for library creators but tricky for testers, as tests likely don’t want to spin up a database just to verify they’ve called the library procedures correctly. The mock library provides utilities for defining opaque values that mocks can interact with.

syntax

(define-opaque clause ...)

 
clause = id
Defines an opaque value and predicate for each id. Each given id is bound to the value, and each predicate is bound to an identifier matching the format of id?.

Examples:
> (define-opaque foo bar)
> foo

#<foo>

> foo?

#<procedure:foo?>

> (foo? foo)

#t

> (equal? foo foo)

#t

If name-id is provided, it is used for the reflective name of each opaque value and predicate. Otherwise, id is used.

Examples:
> (define-opaque foo #:name FOO)
> foo

#<FOO>

> foo?

#<procedure:FOO?>

Additionally, define/mock provides syntax for defining opaque values.

2.5 Mocking Dependencies

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. The mock library provides a shorthand syntax for defining both implementations at once.

syntax

(define/mock header
  opaque-clause history-clause
  mock-clause ...
  body ...)
 
header = id
  | (header arg ...)
  | (header arg ... . rest)
     
opaque-clause = 
  | #:opaque opaque-id:id
  | #:opaque (opaque-id:id ...)
     
history-clause = 
  | #:history history-id:id
     
mock-clause = #:mock mock-id mock-as mock-default
  | #:mock-param param-id mock-as mock-default
     
mock-as = 
  | #:as mock-as-id
     
mock-default = 
  | #:with-behavior behavior-expr
 
  behavior-expr : procedure?
Like define except two versions of id are defined, a normal definition and a definition where each mock-id is defined as a mock within body .... This alternate definition is used whenever id is called within a (with-mocks id ...) form. Each mock uses beavhior-expr as its behavior if provided, and is bound to mock-as-id or mock-id within (with-mocks id ...) for use with checks like check-mock-called-with?. Each opaque-id is defined as an opaque-value using define-opaque, and each behavior-expr may refer to any opaque-id. If provided, history-id is bound as a call-history and each mock uses history-id as an external call history. The id is bound as a rename transformer with define-syntax, but also includes information used by with-mocks to bind id, each mock-id or mock-as-id, and each opaque-id.

Examples:
> (define/mock (foo)
    #:mock bar #:as bar-mock #:with-behavior (const "wow!")
    (bar))
> (define (bar) "bam!")
> (displayln (foo))

bam!

> (with-mocks foo
    (displayln (foo))
    (displayln (mock-calls bar-mock)))

wow!

(#(struct:mock-call bar-mock (arguments) (wow!)))

Opaque values are bound and available in both with-mocks forms and mock behavior expressions, and can be used to represent difficult to construct values like database connections.

Examples:
> (define/mock (foo/opaque)
    #:opaque special
    #:mock bar #:as bar-mock #:with-behavior (const special)
    (bar))
> (define (bar) "bam!")
> special

special: undefined;

 cannot reference an identifier before its definition

  in module: 'program

> (foo/opaque)

"bam!"

> (with-mocks foo/opaque
    (displayln special)
    (displayln (special? (foo/opaque))))

#<special>

#t

If #:as mock-as is not provided, mock-id is used instead. This means with-mocks forms cannot reference both the mock and the mocked dependency simultaneously.

Examples:
> (define/mock (foo/default-binding)
    #:mock bar #:with-behavior (const "wow!")
    (bar))
> (define (bar) "bam!")
> (foo/default-binding)

"bam!"

> (with-mocks foo/default-binding
    (displayln (foo/default-binding))
  
    (displayln (mock-calls bar)))

wow!

(#(struct:mock-call bar (arguments) (wow!)))

If #:with-behavior behavior-expr is not provided, the default behavior of mock is used. If a with-mocks form expects the mock to be called, with-mock-behavior must also be used within the with-mocks form to setup the correct mock behavior.

Examples:
> (define/mock (foo/no-behavior)
    #:mock bar
    (bar))
> (define (bar) "bam!")
> (foo/no-behavior)

"bam!"

> (with-mocks foo/no-behavior
    (foo/no-behavior))

bar: unexpectedly called with arguments

  positional:

  keyword:

Parameters can be mocked by using the #:mock-param form of mock-clause instead of #:mock. When a parameter is mocked, the parameter is expected to contain a procedure and will be parameterized to a mock when the defined procedure is called within the with-mocks form. If #:as mock-as-id is provided, the mock used in the parameter is bound to mock-as-id; otherwise it is available by calling the parameter.

Examples:
> (define current-bar (make-parameter (const "bam!")))
> (define (bar) ((current-bar)))
> (define/mock (foo/param)
    #:mock-param current-bar #:with-behavior (const "wow!")
    (bar))
> (foo/param)

"bam!"

> (with-mocks foo/param
    (displayln (foo/param)))

wow!

Changed in version 2.0 of package mock: Added #:call-history option

Changed in version 2.1 of package mock: Added #:mock-param option

syntax

(with-mocks proc/mocks-id body ...)

Looks up static mocking information associated with proc/mocks-id, which must have been defined with define/mock, and binds a few identifiers within body .... The identifier proc/mocks-id is bound to a separate implementation that calls mocks, and any mocked procedures defined by proc/mocks-id are bound to their mocks. See define/mock for details and an example. The body ... forms are in a new internal definition context surrounded by an enclosing let.

2.6 Stub Implementations

Mocks and define/mock make it possible to test procedures before the procedures they call have been implemented. However, if the procedures called haven’t been defined, a compilation error will occur despite the fact that they’re not used in test. To assist with this, the mock library provides syntax for defining stubs, procedures that haven’t been implemented and throw immediately when called. The term "stub" is used in different ways by different languages and libraries, but that is the definition used by this library.

syntax

(stub header ...)

 
header = id
  | (header arg ...)
  | (header arg ... . rest)
Defines each header as a stub procedure that immediately throws a exn:fail:not-implemented. If header is only an identifier, the procedure accepts any positional and keyword arguments. Otherwise, it accepts exactly the arguments specified in header.

Examples:
> (stub foo (bar v) ((baz k) #:blah v))
> (foo 1 2 #:a 'b)

procedure foo hasn't been implemented

> (bar 1)

procedure bar hasn't been implemented

> (bar 1 2)

bar: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 1

  given: 2

  arguments...:

   1

   2

> (baz 1)

#<procedure:baz>

> ((baz 1) #:blah "blahhhh")

procedure baz hasn't been implemented

struct

(struct exn:fail:not-implemented exn:fail ()
    #:transparent)
An exception type thrown by stubs whenever they’re called.