Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fix bug: Message expectation counts don't work in combination with a …

…stub

- Closes #28.
- Closes #33.
  • Loading branch information...
commit dc1044a8aa0dc0c0989f66e882d565f704ba0647 1 parent 866f34a
Damian Nurzyński authored January 16, 2011 dchelimsky committed January 16, 2011
16  lib/rspec/mocks/message_expectation.rb
@@ -24,6 +24,7 @@ def initialize(error_generator, expectation_ordering, expected_from, sym, method
24 24
         @order_group = expectation_ordering
25 25
         @at_least = nil
26 26
         @at_most = nil
  27
+        @exactly = nil
27 28
         @args_to_yield = []
28 29
         @failed_fast = nil
29 30
         @args_to_yield_were_cloned = false
@@ -286,13 +287,13 @@ def never
286 287
   
287 288
       def once(&block)
288 289
         @method_block = block if block
289  
-        @expected_received_count = 1
  290
+        set_expected_received_count :exactly, 1
290 291
         self
291 292
       end
292 293
   
293 294
       def twice(&block)
294 295
         @method_block = block if block
295  
-        @expected_received_count = 2
  296
+        set_expected_received_count :exactly, 2
296 297
         self
297 298
       end
298 299
   
@@ -307,10 +308,19 @@ def negative_expectation_for?(sym)
307 308
         return false
308 309
       end
309 310
       
  311
+      def actual_received_count_matters?
  312
+        @at_least || @at_most || @exactly
  313
+      end
  314
+
  315
+      def increase_actual_received_count!
  316
+        @actual_received_count += 1
  317
+      end
  318
+
310 319
       protected
311 320
         def set_expected_received_count(relativity, n)
312 321
           @at_least = (relativity == :at_least)
313 322
           @at_most = (relativity == :at_most)
  323
+          @exactly = (relativity == :exactly)
314 324
           @expected_received_count = case n
315 325
             when Numeric
316 326
               n
@@ -324,7 +334,7 @@ def set_expected_received_count(relativity, n)
324 334
         def clear_actual_received_count!
325 335
           @actual_received_count = 0
326 336
         end
327  
-      
  337
+
328 338
     end
329 339
     
330 340
     class NegativeMessageExpectation < MessageExpectation
1  lib/rspec/mocks/proxy.rb
@@ -96,6 +96,7 @@ def message_received(method_name, *args, &block)
96 96
         stub = find_matching_method_stub(method_name, *args)
97 97
 
98 98
         if (stub && expectation && expectation.called_max_times?) || (stub && !expectation)
  99
+          expectation.increase_actual_received_count! if expectation && expectation.actual_received_count_matters?
99 100
           if expectation = find_almost_matching_expectation(method_name, *args)
100 101
             expectation.advise(*args) unless expectation.expected_messages_received?
101 102
           end
78  spec/rspec/mocks/multiple_return_value_spec.rb
@@ -8,7 +8,7 @@ module Mocks
8 8
         @return_values = ["1",2,Object.new]
9 9
         @mock.should_receive(:message).and_return(@return_values[0],@return_values[1],@return_values[2])
10 10
       end
11  
-      
  11
+
12 12
       it "returns values in order to consecutive calls" do
13 13
         @mock.message.should == @return_values[0]
14 14
         @mock.message.should == @return_values[1]
@@ -20,7 +20,7 @@ module Mocks
20 20
         @mock.message.should == @return_values[0]
21 21
         @mock.message.should == @return_values[1]
22 22
         expect { @mock.rspec_verify }.to raise_error(
23  
-          RSpec::Mocks::MockExpectationError, 
  23
+          RSpec::Mocks::MockExpectationError,
24 24
           %Q|(Mock "mock").message(any args)\n    expected: 3 times\n    received: 2 times|
25 25
         )
26 26
       end
@@ -31,10 +31,19 @@ module Mocks
31 31
         @mock.message.should == @return_values[2]
32 32
         @mock.message.should == @return_values[2]
33 33
         expect { @mock.rspec_verify }.to raise_error(
34  
-          RSpec::Mocks::MockExpectationError, 
  34
+          RSpec::Mocks::MockExpectationError,
35 35
           %Q|(Mock "mock").message(any args)\n    expected: 3 times\n    received: 4 times|
36 36
         )
37 37
       end
  38
+
  39
+      it "doesn't complain when there are too many calls but method is stubbed too" do
  40
+        @mock.stub(:message).and_return :stub_result
  41
+        @mock.message.should == @return_values[0]
  42
+        @mock.message.should == @return_values[1]
  43
+        @mock.message.should == @return_values[2]
  44
+        @mock.message.should == :stub_result
  45
+        expect { @mock.rspec_verify }.to_not raise_error(RSpec::Mocks::MockExpectationError)
  46
+      end
38 47
     end
39 48
 
40 49
     describe "a Mock expectation with multiple return values with a specified count equal to the number of values" do
@@ -56,7 +65,7 @@ module Mocks
56 65
         @mock.message.should == @return_values[0]
57 66
         @mock.message.should == @return_values[1]
58 67
         expect { @mock.rspec_verify }.to raise_error(
59  
-          RSpec::Mocks::MockExpectationError, 
  68
+          RSpec::Mocks::MockExpectationError,
60 69
           %Q|(Mock "mock").message(any args)\n    expected: 3 times\n    received: 2 times|
61 70
         )
62 71
       end
@@ -68,7 +77,20 @@ module Mocks
68 77
         @mock.message.should == @return_values[2]
69 78
         @mock.message.should == @return_values[2]
70 79
         expect { @mock.rspec_verify }.to raise_error(
71  
-          RSpec::Mocks::MockExpectationError, 
  80
+          RSpec::Mocks::MockExpectationError,
  81
+          %Q|(Mock "mock").message(any args)\n    expected: 3 times\n    received: 4 times|
  82
+        )
  83
+      end
  84
+
  85
+      it "complains when there are too many calls and method is stubbed too" do
  86
+        third = Object.new
  87
+        @mock.stub(:message).and_return :stub_result
  88
+        @mock.message.should == @return_values[0]
  89
+        @mock.message.should == @return_values[1]
  90
+        @mock.message.should == @return_values[2]
  91
+        @mock.message.should == :stub_result
  92
+        expect { @mock.rspec_verify }.to raise_error(
  93
+          RSpec::Mocks::MockExpectationError,
72 94
           %Q|(Mock "mock").message(any args)\n    expected: 3 times\n    received: 4 times|
73 95
         )
74 96
       end
@@ -79,7 +101,7 @@ module Mocks
79 101
         @mock = RSpec::Mocks::Mock.new("mock")
80 102
         @mock.should_receive(:message).at_least(:twice).with(no_args).and_return(11, 22)
81 103
       end
82  
-      
  104
+
83 105
       it "uses the last return value for subsequent calls" do
84 106
         @mock.message.should equal(11)
85 107
         @mock.message.should equal(22)
@@ -90,10 +112,30 @@ module Mocks
90 112
       it "fails when called less than the specified number" do
91 113
         @mock.message.should equal(11)
92 114
         expect { @mock.rspec_verify }.to raise_error(
93  
-          RSpec::Mocks::MockExpectationError, 
  115
+          RSpec::Mocks::MockExpectationError,
94 116
           %Q|(Mock "mock").message(no args)\n    expected: 2 times\n    received: 1 time|
95 117
         )
96 118
       end
  119
+
  120
+      context "when method is stubbed too" do
  121
+        before { @mock.stub(:message).and_return :stub_result }
  122
+
  123
+        it "uses the stub return value for subsequent calls" do
  124
+          @mock.message.should equal(11)
  125
+          @mock.message.should equal(22)
  126
+          @mock.message.should equal(:stub_result)
  127
+          @mock.rspec_verify
  128
+        end
  129
+
  130
+        it "fails when called less than the specified number" do
  131
+          @mock.message.should equal(11)
  132
+          expect { @mock.rspec_verify }.to raise_error(
  133
+            RSpec::Mocks::MockExpectationError,
  134
+            %Q|(Mock "mock").message(no args)\n    expected: 2 times\n    received: 1 time|
  135
+          )
  136
+        end
  137
+      end
  138
+
97 139
     end
98 140
 
99 141
     describe "a Mock expectation with multiple return values with a specified count larger than the number of values" do
@@ -101,7 +143,7 @@ module Mocks
101 143
         @mock = RSpec::Mocks::Mock.new("mock")
102 144
         @mock.should_receive(:message).exactly(3).times.and_return(11, 22)
103 145
       end
104  
-      
  146
+
105 147
       it "uses the last return value for subsequent calls" do
106 148
         @mock.message.should equal(11)
107 149
         @mock.message.should equal(22)
@@ -112,7 +154,7 @@ module Mocks
112 154
       it "fails when called less than the specified number" do
113 155
         @mock.message.should equal(11)
114 156
         expect { @mock.rspec_verify }.to raise_error(
115  
-          RSpec::Mocks::MockExpectationError, 
  157
+          RSpec::Mocks::MockExpectationError,
116 158
           %Q|(Mock "mock").message(any args)\n    expected: 3 times\n    received: 1 time|
117 159
         )
118 160
       end
@@ -123,10 +165,26 @@ module Mocks
123 165
         @mock.message.should equal(22)
124 166
         @mock.message.should equal(22)
125 167
         expect { @mock.rspec_verify }.to raise_error(
126  
-          RSpec::Mocks::MockExpectationError, 
  168
+          RSpec::Mocks::MockExpectationError,
127 169
           %Q|(Mock "mock").message(any args)\n    expected: 3 times\n    received: 4 times|
128 170
         )
129 171
       end
  172
+
  173
+      context "when method is stubbed too" do
  174
+        before { @mock.stub(:message).and_return :stub_result }
  175
+
  176
+        it "fails when called greater than the specified number" do
  177
+          @mock.message.should equal(11)
  178
+          @mock.message.should equal(22)
  179
+          @mock.message.should equal(22)
  180
+          @mock.message.should equal(:stub_result)
  181
+          expect { @mock.rspec_verify }.to raise_error(
  182
+            RSpec::Mocks::MockExpectationError,
  183
+            %Q|(Mock "mock").message(any args)\n    expected: 3 times\n    received: 4 times|
  184
+          )
  185
+        end
  186
+
  187
+      end
130 188
     end
131 189
   end
132 190
 end

0 notes on commit dc1044a

Please sign in to comment.
Something went wrong with that request. Please try again.