1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#!/usr/bin/env ruby
#---
# Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#+++
require 'flexmock/noop'
require 'flexmock/argument_types'
require 'flexmock/ordering'
require 'flexmock/mock_builder'
class FlexMock
# Mock container methods
#
# Include this module in to get integration with FlexMock. When this module
# is included, mocks may be created with a simple call to the +flexmock+
# method. Mocks created with via the method call will automatically be
# verified in the teardown of the test case.
#
module MockContainer
include Ordering
# Do the flexmock specific teardown stuff. If you need finer control,
# you can use either +flexmock_verify+ or +flexmock_close+.
def flexmock_teardown
flexmock_verify unless flexmock_test_has_failed?
ensure
flexmock_close
end
# Perform verification on all mocks in the container.
def flexmock_verify
flexmock_created_mocks.each do |m|
m.flexmock_verify
end
end
# List of mocks created in this container
def flexmock_created_mocks
@flexmock_created_mocks ||= []
end
# Close all the mock objects in the container. Closing a mock object
# restores any original behavior that was displaced by the mock.
def flexmock_close
flexmock_created_mocks.each do |m|
m.flexmock_teardown
m.pop_flexmock_container
end
@flexmock_created_mocks = []
end
# Create a mocking object in the FlexMock framework. The +flexmock+
# method has a number of options available, depending on just what kind of
# mocking object your require. Mocks created via +flexmock+ will be
# automatically verify during the teardown phase of your test framework.
#
# :call-seq:
# flexmock() { |mock| ... }
# flexmock(name) { |mock| ... }
# flexmock(expect_hash) { |mock| ... }
# flexmock(name, expect_hash) { |mock| ... }
# flexmock(real_object) { |mock| ... }
# flexmock(real_object, name) { |mock| ... }
# flexmock(real_object, name, expect_hash) { |mock| ... }
# flexmock(:base, string, name, expect_hash) { |mock| ... }
#
# <b>Note:</b> A plain flexmock() call without a block will return the
# mock object (the object that interprets <tt>should_receive</tt> and its
# brethern). A flexmock() call that _includes_ a block will return the
# domain objects (the object that will interpret domain messages) since
# the mock will be passed to the block for configuration. With regular
# mocks, this distinction is unimportant because the mock object and the
# domain object are the same object. However, with partial mocks, the
# mock object is separation from the domain object. Keep that distinciton
# in mind.
#
# name ::
# Name of the mock object. If no name is given, "unknown" is used for
# full mocks and "flexmock(<em>real_object</em>)" is used for partial
# mocks.
#
# expect_hash ::
# Hash table of method names and values. Each method/value pair is
# used to setup a simple expectation so that if the mock object
# receives a message matching an entry in the table, it returns
# the associated value. No argument our call count constraints are
# added. Using an expect_hash is identical to calling:
#
# mock.should_receive(method_name).and_return(value)
#
# for each of the method/value pairs in the hash.
#
# real_object ::
# If a real object is given, then a partial mock is constructed
# using the real_object as a base. Partial mocks (formally referred
# to as stubs) behave as a mock object when an expectation is matched,
# and otherwise will behave like the original object. This is useful
# when you want to use a real object for testing, but need to mock out
# just one or two methods.
#
# :base ::
# Forces the following argument to be used as the base of a
# partial mock object. This explicit tag is only needed if you
# want to use a string or a symbol as the mock base (string and
# symbols would normally be interpretted as the mock name).
#
# &block ::
# If a block is given, then the mock object is passed to the block and
# expectations may be configured within the block. When a block is given
# for a partial mock, flexmock will return the domain object rather than
# the mock object.
#
def flexmock(*args, &block)
@flexmock_worker ||= MockBuilder.new(self)
@flexmock_worker.define_a_mock(caller, *args, &block)
end
alias flexstub flexmock
# Remember the mock object / stub in the mock container.
def flexmock_remember(mocking_object)
@flexmock_created_mocks ||= []
@flexmock_created_mocks << mocking_object
mocking_object.push_flexmock_container(self)
mocking_object
end
private
# In frameworks (e.g. MiniTest) passed? will return nil to
# indicate the test isn't over yet. From our point of view we are
# only interested if the test has actually failed, so we wrap the
# raw call to passed? and handle accordingly.
def flexmock_test_has_failed? # :nodoc:
passed? == false
end
end
class ExtensionRegistry
def add_extension(extension)
extensions << extension
end
def extensions
@extensions ||= []
end
end
CONTAINER_HELPER = ExtensionRegistry.new
end
|