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:.
-
#invocation_count ⇒ Object
Returns the value of attribute invocation_count.
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(args) ⇒ 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.
387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/mocha/expectation.rb', line 387 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 |
#invocation_count ⇒ Object
Returns the value of attribute invocation_count.
385 386 387 |
# File 'lib/mocha/expectation.rb', line 385 def invocation_count @invocation_count end |
Instance Method Details
#add_in_sequence_ordering_constraint(sequence) ⇒ Object
403 404 405 |
# File 'lib/mocha/expectation.rb', line 403 def add_in_sequence_ordering_constraint(sequence) sequence.constrain_as_next_in_sequence(self) end |
#add_ordering_constraint(ordering_constraint) ⇒ Object
399 400 401 |
# File 'lib/mocha/expectation.rb', line 399 def add_ordering_constraint(ordering_constraint) @ordering_constraints << ordering_constraint end |
#add_side_effect(side_effect) ⇒ Object
407 408 409 |
# File 'lib/mocha/expectation.rb', line 407 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
415 416 417 |
# File 'lib/mocha/expectation.rb', line 415 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
427 428 429 |
# File 'lib/mocha/expectation.rb', line 427 def invocations_allowed? @cardinality.invocations_allowed?(@invocation_count) end |
#invoke(args) ⇒ Object
435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/mocha/expectation.rb', line 435 def invoke(args) @invocation_count += 1 Mockery.instance.invocation(@mock, method_name, args) 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
423 424 425 |
# File 'lib/mocha/expectation.rb', line 423 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
419 420 421 |
# File 'lib/mocha/expectation.rb', line 419 def matches_method?(method_name) @method_matcher.match?(method_name) end |
#method_signature ⇒ Object
470 471 472 |
# File 'lib/mocha/expectation.rb', line 470 def method_signature "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}" end |
#mocha_inspect ⇒ Object
456 457 458 459 460 461 462 463 464 465 466 467 468 |
# File 'lib/mocha/expectation.rb', line 456 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
411 412 413 |
# File 'lib/mocha/expectation.rb', line 411 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
431 432 433 |
# File 'lib/mocha/expectation.rb', line 431 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
452 453 454 |
# File 'lib/mocha/expectation.rb', line 452 def used? @cardinality.used?(@invocation_count) end |
#verified?(assertion_counter = nil) ⇒ Boolean
447 448 449 450 |
# File 'lib/mocha/expectation.rb', line 447 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 |