File: overview.html

package info (click to toggle)
pmock 0.3-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 932 kB
  • ctags: 816
  • sloc: python: 1,674; makefile: 4
file content (183 lines) | stat: -rw-r--r-- 6,486 bytes parent folder | download | duplicates (2)
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>