File: test_unit_examples_test.rb

package info (click to toggle)
ruby-flexmock 3.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 836 kB
  • sloc: ruby: 7,572; makefile: 6
file content (240 lines) | stat: -rw-r--r-- 6,560 bytes parent folder | download | duplicates (4)
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
require 'flexmock/test_unit'

class TestSimple < Test::Unit::TestCase

  # Simple stubbing of some methods

  def test_simple_mock
    m = flexmock(:pi => 3.1416, :e => 2.71)
    assert_equal 3.1416, m.pi
    assert_equal 2.71, m.e
  end
end


class TestUndefined < Test::Unit::TestCase

  # Create a mock object that returns an undefined object for method calls

  def test_undefined_values
    m = flexmock("mock")
    m.should_receive(:divide_by).with(0).
      and_return_undefined
    assert_equal FlexMock.undefined, m.divide_by(0)
  end
end

class TestDb < Test::Unit::TestCase

  # Expect multiple queries and a single update

  # Multiple calls to the query method will be allows, and calls may
  # have any argument list. Each call to query will return the three
  # element array [1, 2, 3]. The call to update must have a specific
  # argument of 5.

  def test_db
    db = flexmock('db')
    db.should_receive(:query).and_return([1,2,3])
    db.should_receive(:update).with(5).and_return(nil).once

    # Test Code

    db.query
    db.update(5)
  end
end

class TestOrdered < Test::Unit::TestCase

  # Expect all queries before any updates

  # All the query message must occur before any of the update
  # messages.

  def test_query_and_update
    db = flexmock('db')
    db.should_receive(:query).and_return([1,2,3]).ordered
    db.should_receive(:update).and_return(nil).ordered

    # test code here

    db.query
    db.update
  end
end

class MoreOrdered < Test::Unit::TestCase

  # Expect several queries with different parameters

  # The queries should happen after startup but before finish. The
  # queries themselves may happen in any order (because they are in
  # the same order group). The first two queries should happen exactly
  # once, but the third query (which matches any query call with a
  # four character parameter) may be called multiple times (but at
  # least once). Startup and finish must also happen exactly once.

  # Also note that we use the <code>with</code> method to match
  # different argument values to figure out what value to return.

  def test_ordered_queries
    db = flexmock('db')
    db.should_receive(:startup).once.ordered
    db.should_receive(:query).with("CPWR").and_return(12.3).
      once.ordered(:queries)
    db.should_receive(:query).with("MSFT").and_return(10.0).
      once.ordered(:queries)
    db.should_receive(:query).with(/^....$/).and_return(3.3).
      at_least.once.ordered(:queries)
    db.should_receive(:finish).once.ordered

    # Test Code

    db.startup
    db.query("MSFT")
    db.query("XYZY")
    db.query("CPWR")
    db.finish
  end
end

class EvenMoreOrderedTest < Test::Unit::TestCase

  # Same as above, but using the Record Mode interface

  # The record mode interface offers much the same features as the
  # <code>should_receive</code> interface introduced so far, but it
  # allows the messages to be sent directly to a recording object
  # rather than be specified indirectly using a symbol.


  def test_ordered_queries_in_record_mode
    db = flexmock('db')
    db.should_expect do |rec|
      rec.startup.once.ordered
      rec.query("CPWR") { 12.3 }.once.ordered(:queries)
      rec.query("MSFT") { 10.0 }.once.ordered(:queries)
      rec.query(/^....$/) { 3.3 }.at_least.once.ordered(:queries)
      rec.finish.once.ordered
    end

    # Test Code

    db.startup
    db.query("MSFT")
    db.query("XYZY")
    db.query("CPWR")
    db.finish
  end
end

class RecordedTest < Test::Unit::TestCase

  # Using Record Mode to record a known, good algorithm for testing

  # Record mode is nice when you have a known, good algorithm that can
  # use a recording mock object to record the steps. Then you compare
  # the execution of a new algorithm to behavior of the old using the
  # recorded expectations in the mock. For this you probably want to
  # put the recorder in _strict_ mode so that the recorded
  # expectations use exact matching on argument lists, and strict
  # ordering of the method calls.

  # <b>Note:</b> This is most useful when there are no queries on the
  # mock objects, because the query responses cannot be programmed
  # into the recorder object.

  def test_build_xml
    builder = flexmock('builder')
    builder.should_expect do |rec|
      rec.should_be_strict
      known_good_way_to_build_xml(rec)  # record the messages
    end
    new_way_to_build_xml(builder)       # compare to new way
  end

  def known_good_way_to_build_xml(builder)
    builder.person
  end

  def new_way_to_build_xml(builder)
    builder.person
  end

end

class MultipleReturnValueTest < Test::Unit::TestCase

  # Expect multiple calls, returning a different value each time

  # Sometimes you need to return different values for each call to a
  # mocked method. This example shifts values out of a list for this
  # effect.

  def test_multiple_gets
    file = flexmock('file')
    file.should_receive(:gets).with_no_args.
      and_return("line 1\n", "line 2\n")

    # test code here

    file.gets                   # returns "line 1"
    file.gets                   # returns "line 2"
  end
end

class IgnoreUnimportantMessages < Test::Unit::TestCase

  # Ignore uninteresting messages

  # Generally you need to mock only those methods that return an
  # interesting value or wish to assert were sent in a particular
  # manner. Use the <code>should_ignore_missing</code> method to turn
  # on missing method ignoring.

  def test_an_important_message
    m = flexmock('m')
    m.should_receive(:an_important_message).and_return(1).once
    m.should_ignore_missing

    # Test Code

    m.an_important_message
    m.an_unimportant_message
  end

  # When <code>should_ignore_missing</code> is enabled, ignored
  # missing methods will return an undefined object. Any operation on
  # the undefined object will return the undefined object.

end

class PartialMockTest < Test::Unit::TestCase

  # Mock just one method on an existing object

  # The Portfolio class calculate the value of a set of stocks by
  # talking to a quote service via a web service. Since we don't want
  # to use a real web service in our unit tests, we will mock the
  # quote service.

  def test_portfolio_value
    flexmock(QuoteService).new_instances do |m|
      m.should_receive(:quote).and_return(100)
    end
    port = Portfolio.new
    value = port.value     # Portfolio calls QuoteService.quote
    assert_equal 100, value
  end

  class QuoteService
  end

  class Portfolio
    def value
      qs = QuoteService.new
      qs.quote
    end
  end
end