--- title: Mock API inMenu: true --- h2. Mock API RSpec contains a tightly integrated, powerful Mock Object framework. h3. Creating a mock my_mock = mock() This creates a new mock with the given name (a string) and registers it. When the specification finishes, all registered mocks are verified. my_mock = mock(, ) As above, but allows you to specific options to tweak the mock's behaviour. The options argument is a hash. Currently the only supported option is :null_object. Setting this to true instructs the mock to ignore (quietly consume) any messages it hasn't been told to expect - and return itself. I.e.: my_mock = mock("blah", :null_object => true) h3. Expecting Messages my_mock.should_receive() The message argument is a symbol that is the name of a message that you want the mock to expect. h3. Expecting Arguments my_mock.should_receive(:msg).with() for example: my_mock.should_receive(:msg).with(1, 2, 3) The args argument is a series of arguments (e.g. 1, 2, 3) that are expected to be passed as arguments to the associated message. my_mock.should_receive(:msg).with(:no_args) The message (msg) is expected to be passed no arguments. my_mock.should_receive(:msg).with(:any_args) Any arguments (and any number of arguments) are to be accepted. This includes cases where no arguments are provided. *This is the default when no with() clause is specified.* Even so, sometimes you want to be explicit about it. h3. Argument Constraints Constraints can be placed on individual arguments which are looser than value equivalence (as above). h4. :anything accepts any value for this argument, e.g.: my_mock.should_receive(:msg).with(1, :anything, "A") h4. :numeric accepts any numeric value for this argument, e.g.: my_mock.should_receive(:msg).with(a, :numeric, "b") h4. :boolean accepts a boolean value for this argument, e.g.: my_mock.should_receive(:msg).with(a, :boolean, "b") h4. :string accepts any string for this argument, e.g.: my_mock.should_receive(:msg).with(a, :string, "b") h4. duck_type(message(s)) accepts any object that responds to the prescribed message(s), e.g.: #accepts a Fixnum for the second arg my_mock.should_receive(:msg).with(a, duck_type(:abs, :div), "b") h3. Receive Counts my_mock.should_receive(:msg).never An exception is raised if the message is ever received. This is equivalent to not specifying the reception of :msg, but it's more declarative and useful for humans. my_mock.should_receive(:msg).any_number_of_times The message can be received 0 or more times. my_mock.should_receive(:msg).once An exception is raised if the message is never received, or it is received more than once. my_mock.should_receive(:msg).twice An exception is raised if the message is received anything but two times. my_mock.should_receive(:msg).exactly(n).times An exception is raised if the message is received anything but n times. my_mock.should_receive(:msg).at_least(:once) An exception is raised if the message is never received. my_mock.should_receive(:msg).at_least(:twice) An exception is raised if the message is never received or is received only once. my_mock.should_receive(:msg).at_least(n).times An exception is raised if the message is received fewer than n times. h3. Return Values h4. Single return value my_mock.should_receive(:msg).once_and_return() Each time the expected message is received, value will be returned as the result. h4. Consequtive return values and_return([, , ..., ]) When the expected message is received, value-i will be returned as the result for the ith reception of the message. After the message has been received i times, value-n is returned for all subsequent receives. *Note:* if you wish to have a single return value that is an array, you must use this form, with one item that is the array to return. Otherwise your array will be interpreted as a series of return values. For example: and_return([[1, 2, 3]]) h4. Computed return value my_mock.should_receive(:msg).once_and_return {...} When the expected message is received, the result of evaluating the supplied block will be returned as the result. The block is passed any arguments passed as arguments of the message. This capability can be used to compute return values based on the arguments. For example: my_mock.should_receive(:msg).with(:numeric, :numeric) once_and_return {|a, b| a + b} h3. Raising and Throwing my_mock.should_receive(:msg).once_and_raise() my_mock.should_receive(:msg).once_and_throw() These instruct the mock to raise an exception or throw a symbol, respectively, instead of returning a value. h3. Yielding my_mock.should_receive(:msg).once_and_yield([, , ..., ]) When the expected message is received, the mock will yield the values to the passed block. h3. Ordering There are times when you want to specify the order of messages sent to a mock. It shouldn't be the case very often, but it can be handy at times. Labeling expectations as being ordered is done by the ordered call: my_mock.should_receive(:flip).once.ordered my_mock.should_receive(:flop).once.ordered If the send of flop is seen before flip the specification will fail. Of course, chains of ordered expectations can be set up: my_mock.should_receive(:one).ordered my_mock.should_receive(:two).ordered my_mock.should_receive(:three).ordered The expected order is the order in which the expectations are declared. Order-independent expectations can be set anywhere in the expectation sequence, in any order. Only the order of expectations tagged with the ordered call is significant. Likewise, calls to order-independent methods can be made in any order, even interspersed with calls to order-dependent methods. For example: my_mock.should_receive(:zero) my_mock.should_receive(:one).ordered my_mock.should_receive(:two).ordered my_mock.should_receive(:one_and_a_half) # This will pass: my_mock.one my_mock.one_and_a_half my_mock.zero my_mock.two h3. Arbitrary Handling of Received Messages You can supply a block to a message expectation. When the message is received by the mock, the block is passed any arguments and evaluated. The result is the return value of the block. For example: my_mock.should_receive(:msg) { |a, b| a.should_be true b.should_not_contain('mice') "Chunky bacon!" } This allows arbitrary argument validation and result computation. It's handy and kind of cool to be able to do this, but it is advised to not use this form in most situations. Mocks should not be functional. They should be completely declarative. That said, it's sometimes useful to give them some minimal behaviour.