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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
<html>
<head>
<title>pMock: Overview of API</title>
</head>
<body>
<h1>Overview of the pMock API</h1>
<ul>
<li><a href="#CreatingMocks">Creating mocks<a/></li>
<li><a href="#ArgumentExpectations">Argument expectations<a/></li>
<li><a href="#NumberOfCallsToTheSameMethod">Number of calls to the same method</a></li>
<li><a href="#CallOrderExpectations">Call order expectations<a/></li>
<li><a href="#MockBehaviour">Mock behaviour<a/></li>
<li><a href="#Stubs">Stubs<a/></li>
<li><a href="#DefaultBehaviourForUndefinedMethods">Default behaviour for undefined methods<a/></li>
<li><a href="#FromImports"><code>from</code> imports<a/></li>
<li><a href="#TestBaseClass">Test base class<a/></li>
<li><a href="#FurtherInformation">Further information<a/></li>
</ul>
<h2 id="CreatingMocks">Creating mocks</h2>
A mock object is created to represent a real object for the purposes of a unit test. Using a mock object rather than the real object can be useful if the real object is difficult to construct, hasn't been written yet or causes awkward side effects in use.
<pre>
import pmock
...
mock = pmock.Mock()
</pre>
Expectations are defined for the methods that are meant to be called on the mock object.
<pre>
mock.expects(pmock.once()).render()
</pre>
The mock can now be called with the expected method.
<pre>
mock.render()
</pre>
Calling the mock with unexpected methods causes an exception to be raised.
<p>When the mock objects have been set up, they are then used in the unit test as the real objects would have been.
<pre>
pictures = [mock]
gallery = Gallery(pictures)
gallery.render()
</pre>
After the test's normal assertions have been made, an assertion that the mock's expectations have been satisfied should be made.
<pre>
mock.verify()
</pre>
If any of the mock's expectations haven't been satisfied, such as an expected method not having been called, then the <code>verify</code> call raises an exception.
<h2 id="ArgumentExpectations">Argument expectations</h2>
Expectations can be set on the arguments passed to the mock's methods.
<pre>
mock.expects(pmock.once()).render(pmock.eq(640), pmock.eq(480))
</pre>
The arguments to the expectation's mocked method are constraint objects which are evaluated on the actual arguments when a call is made to the mock object. If an argument doesn't satisfy its constraint then the expectation remains unsatisfied.
<pre>
mock.expects(pmock.once()).render(brush=pmock.same(print.BIG_BRUSH))
</pre>
More flexible argument constraints can be defined using a slightly more verbose set of methods.
<pre>
mock.expects(pmock.once()).method("render") # any arguments allowed
mock.expects(pmock.once()).method("render").with_at_least(brush=pmock.same(print.BIG_BRUSH))
</pre>
<h2 id="NumberOfCallsToTheSameMethod">Number of calls to the same method</h2>
The argument to the <code>expects</code> method describes how often the expected method can be called.
<pre>
mock.expects(pmock.once()).boil()
mock.expects(pmock.at_least_once()).simmer()
mock.expects(pmock.never()).fry()
</pre>
<h2 id="CallOrderExpectations">Call order expectations</h2>
The order of calls to the mock object can be described with the <code>after</code> method.
<pre>
mock.expects(pmock.once()).invalidate()
mock.expects(pmock.once()).render().after("invalidate")
</pre>
<p>An explicit id can be set for an expectation and used in the <code>after</code> method instead of using the method name.
<pre>
mock.expects(pmock.once()).add(pmock.eq(10)).id("add #1")
mock.expects(pmock.once()).add(pmock.eq(15)).id("add #2").after("add #1")
mock.expects(pmock.once()).add(pmock.eq(5)).after("add #2")
</pre>
The order of calls can also be defined across different mock objects.
<pre>
other_mock = pmock.Mock()
other_mock.expects(pmock.once()).add()
mock = pmock.Mock()
mock.expects(pmock.once()).sum().after("add", other_mock)
</pre>
<h2 id="MockBehaviour">Mock behaviour</h2>
The mocked methods can be provided with simple behaviours using the <code>will</code> method.
<pre>
mock.expects(pmock.once()).calculate().will(pmock.return_value(20))
mock.expects(pmock.once()).consume().will(pmock.raise_exception(RuntimeError("invalid")))
</pre>
<h2 id="Stubs">Stubs</h2>
Stubs allow behaviours to be specified for methods that can be called any number of times and are not to be included in the mock's verification check.
<pre>
mock.stubs().sleep().will(pmock.return_value(True))
</pre>
<h2 id="DefaultBehaviourForUndefinedMethods">Default behaviour for undefined methods</h2>
When an undefined method is called an exception is normally raised. However this behviour can be overridden by supplying a stub object to the <code>Mock</code> instance's <code>set_default_stub</code> method.
<pre>
mock.set_default_stub(pmock.return_value("legs"))
mock.crazy()
</pre>
<h2 id="FromImports">From imports</h2>
The test code can be made more concise by importing the pmock module's public classes and functions into the test module.
<pre>
from pmock import *
mock = Mock()
mock.expects(once()).calculate(eq(34), eq(2)).will(return_value(68))
</pre>
<h2 id="TestBaseClass">Test base class</h2>
The <code>MockTestCase</code> class is a convenience base class for tests. It provides the <code>mock</code> method for creating mock objects that will be automatically verified after the test method has run. The verify calls are made to the mock object after <code>tearDown</code> has been called.
<pre>
class FooTest(pmock.MockTestCase):
def test_involving_mocks(self):
bar = self.mock()
bar.expects(pmock.once()).baz()
qux.quux(bar)
# no need for verify call as its done by MockTestCase
</pre>
<h2 id="FurtherInformation">Further information</h2>
<p>Looking at the pMock <a href="http://cvs.sourceforge.net/viewcvs.py/pmock/pmock/src/acceptance_tests.py">acceptance tests</a> may be helpful in further clarifying the behaviour of the module.</p>
<p>The <a href="http://www.mockobjects.com">mock objects</a> and <a href="http://www.jmock.org">jmock</a> websites contain useful information on mock objects and their use as a testing technique.</p>
<p>Martin Fowler has written an <a href="http://martinfowler.com/articles/mocksArentStubs.html">interesting article about mock objects</a> and the style of unit testing that uses them.</p>
</body>
</html>
|