Class: Mocha::Expectation
Overview
Methods on expectations returned from Mock#expects, Mock#stubs, Object#expects and Object#stubs.
Instance Attribute Summary collapse
-
#backtrace ⇒ Object
readonly
:stopdoc:.
Instance Method Summary collapse
- #add_in_sequence_ordering_constraint(sequence) ⇒ Object
- #add_ordering_constraint(ordering_constraint) ⇒ Object
- #add_side_effect(side_effect) ⇒ Object
-
#at_least(minimum_number_of_times) ⇒ Object
:call-seq: at_least(minimum_number_of_times) -> expectation.
-
#at_least_once ⇒ Object
:call-seq: at_least_once() -> expectation.
-
#at_most(maximum_number_of_times) ⇒ Object
:call-seq: at_most(maximum_number_of_times) -> expectation.
-
#at_most_once ⇒ Object
:call-seq: at_most_once() -> expectation.
- #in_correct_order? ⇒ Boolean
-
#in_sequence(*sequences) ⇒ Object
:call-seq: in_sequence(*sequences) -> expectation.
-
#initialize(mock, expected_method_name, backtrace = nil) ⇒ Expectation
constructor
A new instance of Expectation.
- #invocations_allowed? ⇒ Boolean
- #invoke ⇒ Object
- #match?(actual_method_name, *actual_parameters) ⇒ Boolean
- #matches_method?(method_name) ⇒ Boolean
- #method_signature ⇒ Object
- #mocha_inspect ⇒ Object
-
#multiple_yields(*parameter_groups) ⇒ Object
:call-seq: multiple_yields(*parameter_groups) -> expectation.
-
#never ⇒ Object
:call-seq: never() -> expectation.
-
#once ⇒ Object
:call-seq: once() -> expectation.
- #perform_side_effects ⇒ Object
-
#raises(exception = RuntimeError, message = nil) ⇒ Object
:call-seq: raises(exception = RuntimeError, message = nil) -> expectation.
-
#returns(*values) ⇒ Object
:call-seq: returns(value) -> expectation returns(*values) -> expectation.
- #satisfied? ⇒ Boolean
-
#then(*parameters) ⇒ Object
:call-seq: then() -> expectation then(state_machine.is(state)) -> expectation.
-
#times(range) ⇒ Object
:call-seq: times(range) -> expectation.
-
#twice ⇒ Object
:call-seq: twice() -> expectation.
- #used? ⇒ Boolean
- #verified?(assertion_counter = nil) ⇒ Boolean
-
#when(state_predicate) ⇒ Object
:call-seq: when(state_machine.is(state)) -> exception.
-
#with(*expected_parameters, &matching_block) ⇒ Object
:call-seq: with(*expected_parameters, &matching_block) -> expectation.
-
#yields(*parameters) ⇒ Object
:call-seq: yields(*parameters) -> expectation.
Constructor Details
#initialize(mock, expected_method_name, backtrace = nil) ⇒ Expectation
Returns a new instance of Expectation.
386 387 388 389 390 391 392 393 394 395 396 |
# File 'lib/mocha/expectation.rb', line 386 def initialize(mock, expected_method_name, backtrace = nil) @mock = mock @method_matcher = MethodMatcher.new(expected_method_name.to_sym) @parameters_matcher = ParametersMatcher.new @ordering_constraints = [] @side_effects = [] @cardinality, @invocation_count = Cardinality.exactly(1), 0 @return_values = ReturnValues.new @yield_parameters = YieldParameters.new @backtrace = backtrace || caller end |
Instance Attribute Details
#backtrace ⇒ Object (readonly)
:stopdoc:
384 385 386 |
# File 'lib/mocha/expectation.rb', line 384 def backtrace @backtrace end |
Instance Method Details
#add_in_sequence_ordering_constraint(sequence) ⇒ Object
402 403 404 |
# File 'lib/mocha/expectation.rb', line 402 def add_in_sequence_ordering_constraint(sequence) sequence.constrain_as_next_in_sequence(self) end |
#add_ordering_constraint(ordering_constraint) ⇒ Object
398 399 400 |
# File 'lib/mocha/expectation.rb', line 398 def add_ordering_constraint(ordering_constraint) @ordering_constraints << ordering_constraint end |
#add_side_effect(side_effect) ⇒ Object
406 407 408 |
# File 'lib/mocha/expectation.rb', line 406 def add_side_effect(side_effect) @side_effects << side_effect end |
#at_least(minimum_number_of_times) ⇒ Object
:call-seq: at_least(minimum_number_of_times) -> expectation
Modifies expectation so that the expected method must be called at least a minimum_number_of_times
.
object = mock()
object.expects(:expected_method).at_least(2)
3.times { object.expected_method }
# => verify succeeds
object = mock()
object.expects(:expected_method).at_least(2)
object.expected_method
# => verify fails
123 124 125 126 |
# File 'lib/mocha/expectation.rb', line 123 def at_least(minimum_number_of_times) @cardinality = Cardinality.at_least(minimum_number_of_times) self end |
#at_least_once ⇒ Object
:call-seq: at_least_once() -> expectation
Modifies expectation so that the expected method must be called at least once.
object = mock()
object.expects(:expected_method).at_least_once
object.expected_method
# => verify succeeds
object = mock()
object.expects(:expected_method).at_least_once
# => verify fails
139 140 141 142 |
# File 'lib/mocha/expectation.rb', line 139 def at_least_once at_least(1) self end |
#at_most(maximum_number_of_times) ⇒ Object
:call-seq: at_most(maximum_number_of_times) -> expectation
Modifies expectation so that the expected method must be called at most a maximum_number_of_times
.
object = mock()
object.expects(:expected_method).at_most(2)
2.times { object.expected_method }
# => verify succeeds
object = mock()
object.expects(:expected_method).at_most(2)
3.times { object.expected_method }
# => verify fails
156 157 158 159 |
# File 'lib/mocha/expectation.rb', line 156 def at_most(maximum_number_of_times) @cardinality = Cardinality.at_most(maximum_number_of_times) self end |
#at_most_once ⇒ Object
:call-seq: at_most_once() -> expectation
Modifies expectation so that the expected method must be called at most once.
object = mock()
object.expects(:expected_method).at_most_once
object.expected_method
# => verify succeeds
object = mock()
object.expects(:expected_method).at_most_once
2.times { object.expected_method }
# => verify fails
173 174 175 176 |
# File 'lib/mocha/expectation.rb', line 173 def at_most_once() at_most(1) self end |
#in_correct_order? ⇒ Boolean
414 415 416 |
# File 'lib/mocha/expectation.rb', line 414 def in_correct_order? @ordering_constraints.all? { |ordering_constraint| ordering_constraint.allows_invocation_now? } end |
#in_sequence(*sequences) ⇒ Object
:call-seq: in_sequence(*sequences) -> expectation
Constrains this expectation so that it must be invoked at the current point in the sequence.
To expect a sequence of invocations, write the expectations in order and add the in_sequence(sequence) clause to each one.
Expectations in a sequence can have any invocation count.
If an expectation in a sequence is stubbed, rather than expected, it can be skipped in the sequence.
See also API#sequence.
breakfast = sequence('breakfast')
egg = mock('egg')
egg.expects(:crack).in_sequence(breakfast)
egg.expects(:fry).in_sequence(breakfast)
egg.expects(:eat).in_sequence(breakfast)
377 378 379 380 |
# File 'lib/mocha/expectation.rb', line 377 def in_sequence(*sequences) sequences.each { |sequence| add_in_sequence_ordering_constraint(sequence) } self end |
#invocations_allowed? ⇒ Boolean
426 427 428 |
# File 'lib/mocha/expectation.rb', line 426 def invocations_allowed? @cardinality.invocations_allowed?(@invocation_count) end |
#invoke ⇒ Object
434 435 436 437 438 439 440 441 442 443 |
# File 'lib/mocha/expectation.rb', line 434 def invoke @invocation_count += 1 perform_side_effects() if block_given? then @yield_parameters.next_invocation.each do |yield_parameters| yield(*yield_parameters) end end @return_values.next end |
#match?(actual_method_name, *actual_parameters) ⇒ Boolean
422 423 424 |
# File 'lib/mocha/expectation.rb', line 422 def match?(actual_method_name, *actual_parameters) @method_matcher.match?(actual_method_name) && @parameters_matcher.match?(actual_parameters) && in_correct_order? end |
#matches_method?(method_name) ⇒ Boolean
418 419 420 |
# File 'lib/mocha/expectation.rb', line 418 def matches_method?(method_name) @method_matcher.match?(method_name) end |
#method_signature ⇒ Object
468 469 470 |
# File 'lib/mocha/expectation.rb', line 468 def method_signature "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}" end |
#mocha_inspect ⇒ Object
454 455 456 457 458 459 460 461 462 463 464 465 466 |
# File 'lib/mocha/expectation.rb', line 454 def mocha_inspect = "#{@cardinality.mocha_inspect}, " << case @invocation_count when 0 then "not yet invoked" when 1 then "already invoked once" when 2 then "already invoked twice" else "already invoked #{@invocation_count} times" end << ": " << method_signature << "; #{@ordering_constraints.map { |oc| oc.mocha_inspect }.join("; ")}" unless @ordering_constraints.empty? end |
#multiple_yields(*parameter_groups) ⇒ Object
:call-seq: multiple_yields(*parameter_groups) -> expectation
Modifies expectation so that when the expected method is called, it yields multiple times per invocation with the specified parameter_groups
.
object = mock()
object.expects(:expected_method).multiple_yields(['result_1', 'result_2'], ['result_3'])
yielded_values = []
object.expected_method { |*values| yielded_values << values }
yielded_values # => [['result_1', 'result_2'], ['result_3]]
May be called multiple times on the same expectation for consecutive invocations. Also see Expectation#then.
object = mock()
object.stubs(:expected_method).multiple_yields([1, 2], [3]).then.multiple_yields([4], [5, 6])
yielded_values_from_first_invocation = []
yielded_values_from_second_invocation = []
object.expected_method { |*values| yielded_values_from_first_invocation << values } # first invocation
object.expected_method { |*values| yielded_values_from_second_invocation << values } # second invocation
yielded_values_from_first_invocation # => [[1, 2], [3]]
yielded_values_from_second_invocation # => [[4], [5, 6]]
247 248 249 250 |
# File 'lib/mocha/expectation.rb', line 247 def multiple_yields(*parameter_groups) @yield_parameters.multiple_add(*parameter_groups) self end |
#never ⇒ Object
:call-seq: never() -> expectation
Modifies expectation so that the expected method must never be called.
object = mock()
object.expects(:expected_method).never
object.expected_method
# => verify fails
object = mock()
object.expects(:expected_method).never
object.expected_method
# => verify succeeds
106 107 108 109 |
# File 'lib/mocha/expectation.rb', line 106 def never @cardinality = Cardinality.exactly(0) self end |
#once ⇒ Object
:call-seq: once() -> expectation
Modifies expectation so that the expected method must be called exactly once. Note that this is the default behaviour for an expectation, but you may wish to use it for clarity/emphasis.
object = mock()
object.expects(:expected_method).once
object.expected_method
# => verify succeeds
object = mock()
object.expects(:expected_method).once
object.expected_method
object.expected_method
# => verify fails
object = mock()
object.expects(:expected_method).once
# => verify fails
89 90 91 92 |
# File 'lib/mocha/expectation.rb', line 89 def once @cardinality = Cardinality.exactly(1) self end |
#perform_side_effects ⇒ Object
410 411 412 |
# File 'lib/mocha/expectation.rb', line 410 def perform_side_effects @side_effects.each { |side_effect| side_effect.perform } end |
#raises(exception = RuntimeError, message = nil) ⇒ Object
:call-seq: raises(exception = RuntimeError, message = nil) -> expectation
Modifies expectation so that when the expected method is called, it raises the specified exception
with the specified message
.
object = mock()
object.expects(:expected_method).raises(Exception, 'message')
object.expected_method # => raises exception of class Exception and with message 'message'
May be called multiple times on the same expectation. Also see Expectation#then.
object = mock()
object.stubs(:expected_method).raises(Exception1).then.raises(Exception2)
object.expected_method # => raises exception of class Exception1
object.expected_method # => raises exception of class Exception2
May be called in conjunction with Expectation#returns on the same expectation.
object = mock()
object.stubs(:expected_method).raises(Exception).then.returns(2, 3)
object.expected_method # => raises exception of class Exception1
object.expected_method # => 2
object.expected_method # => 3
305 306 307 308 |
# File 'lib/mocha/expectation.rb', line 305 def raises(exception = RuntimeError, = nil) @return_values += ReturnValues.new(ExceptionRaiser.new(exception, )) self end |
#returns(*values) ⇒ Object
:call-seq: returns(value) -> expectation
returns(*values) -> expectation
Modifies expectation so that when the expected method is called, it returns the specified value
.
object = mock()
object.stubs(:stubbed_method).returns('result')
object.stubbed_method # => 'result'
object.stubbed_method # => 'result'
If multiple values
are given, these are returned in turn on consecutive calls to the method.
object = mock()
object.stubs(:stubbed_method).returns(1, 2)
object.stubbed_method # => 1
object.stubbed_method # => 2
May be called multiple times on the same expectation. Also see Expectation#then.
object = mock()
object.stubs(:expected_method).returns(1, 2).then.returns(3)
object.expected_method # => 1
object.expected_method # => 2
object.expected_method # => 3
May be called in conjunction with Expectation#raises on the same expectation.
object = mock()
object.stubs(:expected_method).returns(1, 2).then.raises(Exception)
object.expected_method # => 1
object.expected_method # => 2
object.expected_method # => raises exception of class Exception1
Note that in Ruby a method returning multiple values is exactly equivalent to a method returning an Array of those values.
object = mock()
object.stubs(:expected_method).returns([1, 2])
x, y = object.expected_method
x # => 1
y # => 2
283 284 285 286 |
# File 'lib/mocha/expectation.rb', line 283 def returns(*values) @return_values += ReturnValues.build(*values) self end |
#satisfied? ⇒ Boolean
430 431 432 |
# File 'lib/mocha/expectation.rb', line 430 def satisfied? @cardinality.satisfied?(@invocation_count) end |
#then(*parameters) ⇒ Object
:call-seq: then() -> expectation
then(state_machine.is(state)) -> expectation
then()
is used as syntactic sugar to improve readability. It has no effect on state of the expectation.
object = mock()
object.stubs(:expected_method).returns(1, 2).then.raises(Exception).then.returns(4)
object.expected_method # => 1
object.expected_method # => 2
object.expected_method # => raises exception of class Exception
object.expected_method # => 4
then(state_machine.is(state))
is used to change the state_machine
to the specified state
when the invocation occurs.
See also API#states, StateMachine and Expectation#when.
power = states('power').starts_as('off')
radio = mock('radio')
radio.expects(:switch_on).then(power.is('on'))
radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
radio.expects(:adjust_volume).with(+5).when(power.is('on'))
radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
radio.expects(:adjust_volume).with(-5).when(power.is('on'))
radio.expects(:switch_off).then(power.is('off'))
333 334 335 336 337 338 339 |
# File 'lib/mocha/expectation.rb', line 333 def then(*parameters) if parameters.length == 1 state = parameters.first add_side_effect(ChangeStateSideEffect.new(state)) end self end |
#times(range) ⇒ Object
:call-seq: times(range) -> expectation
Modifies expectation so that the number of calls to the expected method must be within a specific range
.
range
can be specified as an exact integer or as a range of integers
object = mock()
object.expects(:expected_method).times(3)
3.times { object.expected_method }
# => verify succeeds
object = mock()
object.expects(:expected_method).times(3)
2.times { object.expected_method }
# => verify fails
object = mock()
object.expects(:expected_method).times(2..4)
3.times { object.expected_method }
# => verify succeeds
object = mock()
object.expects(:expected_method).times(2..4)
object.expected_method
# => verify fails
41 42 43 44 |
# File 'lib/mocha/expectation.rb', line 41 def times(range) @cardinality = Cardinality.times(range) self end |
#twice ⇒ Object
:call-seq: twice() -> expectation
Modifies expectation so that the expected method must be called exactly twice.
object = mock()
object.expects(:expected_method).twice
object.expected_method
object.expected_method
# => verify succeeds
object = mock()
object.expects(:expected_method).twice
object.expected_method
object.expected_method
object.expected_method
# => verify fails
object = mock()
object.expects(:expected_method).twice
object.expected_method
# => verify fails
66 67 68 69 |
# File 'lib/mocha/expectation.rb', line 66 def twice @cardinality = Cardinality.exactly(2) self end |
#used? ⇒ Boolean
450 451 452 |
# File 'lib/mocha/expectation.rb', line 450 def used? @cardinality.used?(@invocation_count) end |
#verified?(assertion_counter = nil) ⇒ Boolean
445 446 447 448 |
# File 'lib/mocha/expectation.rb', line 445 def verified?(assertion_counter = nil) assertion_counter.increment if assertion_counter && @cardinality. @cardinality.verified?(@invocation_count) end |
#when(state_predicate) ⇒ Object
:call-seq: when(state_machine.is(state)) -> exception
Constrains the expectation to occur only when the state_machine
is in the named state
.
See also API#states, StateMachine#starts_as and Expectation#then.
power = states('power').starts_as('off')
radio = mock('radio')
radio.expects(:switch_on).then(power.is('on'))
radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
radio.expects(:adjust_volume).with(+5).when(power.is('on'))
radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
radio.expects(:adjust_volume).with(-5).when(power.is('on'))
radio.expects(:switch_off).then(power.is('off'))
355 356 357 358 |
# File 'lib/mocha/expectation.rb', line 355 def when(state_predicate) add_ordering_constraint(InStateOrderingConstraint.new(state_predicate)) self end |
#with(*expected_parameters, &matching_block) ⇒ Object
:call-seq: with(*expected_parameters, &matching_block) -> expectation
Modifies expectation so that the expected method must be called with expected_parameters
.
object = mock()
object.expects(:expected_method).with(:param1, :param2)
object.expected_method(:param1, :param2)
# => verify succeeds
object = mock()
object.expects(:expected_method).with(:param1, :param2)
object.expected_method(:param3)
# => verify fails
May be used with parameter matchers in Mocha::ParameterMatchers.
If a matching_block
is given, the block is called with the parameters passed to the expected method. The expectation is matched if the block evaluates to true
.
object = mock()
object.expects(:expected_method).with() { |value| value % 4 == 0 }
object.expected_method(16)
# => verify succeeds
object = mock()
object.expects(:expected_method).with() { |value| value % 4 == 0 }
object.expected_method(17)
# => verify fails
203 204 205 206 |
# File 'lib/mocha/expectation.rb', line 203 def with(*expected_parameters, &matching_block) @parameters_matcher = ParametersMatcher.new(expected_parameters, &matching_block) self end |
#yields(*parameters) ⇒ Object
:call-seq: yields(*parameters) -> expectation
Modifies expectation so that when the expected method is called, it yields with the specified parameters
.
object = mock()
object.expects(:expected_method).yields('result')
yielded_value = nil
object.expected_method { |value| yielded_value = value }
yielded_value # => 'result'
May be called multiple times on the same expectation for consecutive invocations. Also see Expectation#then.
object = mock()
object.stubs(:expected_method).yields(1).then.yields(2)
yielded_values_from_first_invocation = []
yielded_values_from_second_invocation = []
object.expected_method { |value| yielded_values_from_first_invocation << value } # first invocation
object.expected_method { |value| yielded_values_from_second_invocation << value } # second invocation
yielded_values_from_first_invocation # => [1]
yielded_values_from_second_invocation # => [2]
225 226 227 228 |
# File 'lib/mocha/expectation.rb', line 225 def yields(*parameters) @yield_parameters.add(*parameters) self end |