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.
391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/mocha/expectation.rb', line 391 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:
388 389 390 |
# File 'lib/mocha/expectation.rb', line 388 def backtrace @backtrace end |
#invocation_count ⇒ Object
Returns the value of attribute invocation_count.
389 390 391 |
# File 'lib/mocha/expectation.rb', line 389 def invocation_count @invocation_count end |
Instance Method Details
#add_in_sequence_ordering_constraint(sequence) ⇒ Object
407 408 409 |
# File 'lib/mocha/expectation.rb', line 407 def add_in_sequence_ordering_constraint(sequence) sequence.constrain_as_next_in_sequence(self) end |
#add_ordering_constraint(ordering_constraint) ⇒ Object
403 404 405 |
# File 'lib/mocha/expectation.rb', line 403 def add_ordering_constraint(ordering_constraint) @ordering_constraints << ordering_constraint end |
#add_side_effect(side_effect) ⇒ Object
411 412 413 |
# File 'lib/mocha/expectation.rb', line 411 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
419 420 421 |
# File 'lib/mocha/expectation.rb', line 419 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)
381 382 383 384 |
# File 'lib/mocha/expectation.rb', line 381 def in_sequence(*sequences) sequences.each { |sequence| add_in_sequence_ordering_constraint(sequence) } self end |
#invocations_allowed? ⇒ Boolean
431 432 433 |
# File 'lib/mocha/expectation.rb', line 431 def invocations_allowed? @cardinality.invocations_allowed?(@invocation_count) end |
#invoke(args) ⇒ Object
439 440 441 442 443 444 445 446 447 448 449 |
# File 'lib/mocha/expectation.rb', line 439 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
427 428 429 |
# File 'lib/mocha/expectation.rb', line 427 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
423 424 425 |
# File 'lib/mocha/expectation.rb', line 423 def matches_method?(method_name) @method_matcher.match?(method_name) end |
#method_signature ⇒ Object
474 475 476 |
# File 'lib/mocha/expectation.rb', line 474 def method_signature "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}" end |
#mocha_inspect ⇒ Object
460 461 462 463 464 465 466 467 468 469 470 471 472 |
# File 'lib/mocha/expectation.rb', line 460 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
415 416 417 |
# File 'lib/mocha/expectation.rb', line 415 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
i.e. calls Kernel#raise(exception, message).
object = mock()
object.expects(:expected_method).raises(Exception, 'message')
object.expected_method # => raises exception of class Exception and with message 'message'
Note that if you have a custom exception class with extra constructor parameters, you can pass in an instance of the exception (just as you can for Kernel#raise).
object = mock()
object.expects(:expected_method).raises(MyException.new('message', 1, 2, 3))
object.expected_method # => raises the specified instance of MyException
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
309 310 311 312 |
# File 'lib/mocha/expectation.rb', line 309 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
435 436 437 |
# File 'lib/mocha/expectation.rb', line 435 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'))
337 338 339 340 341 342 343 |
# File 'lib/mocha/expectation.rb', line 337 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
456 457 458 |
# File 'lib/mocha/expectation.rb', line 456 def used? @cardinality.used?(@invocation_count) end |
#verified?(assertion_counter = nil) ⇒ Boolean
451 452 453 454 |
# File 'lib/mocha/expectation.rb', line 451 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'))
359 360 361 362 |
# File 'lib/mocha/expectation.rb', line 359 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 |