Module: RSpec::Mocks::Syntax Private

Defined in:
lib/rspec/mocks/syntax.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Provides methods for enabling and disabling the available syntaxes provided by rspec-mocks.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.default_should_syntax_hostObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Determines where the methods like should_receive, and stub are added.



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/rspec/mocks/syntax.rb', line 168

def self.default_should_syntax_host
  # JRuby 1.7.4 introduces a regression whereby `defined?(::BasicObject) => nil`
  # yet `BasicObject` still exists and patching onto ::Object breaks things
  # e.g. SimpleDelegator expectations won't work
  #
  # See: https://github.com/jruby/jruby/issues/814
  if defined?(JRUBY_VERSION) && JRUBY_VERSION == '1.7.4' && RUBY_VERSION.to_f > 1.8
    return ::BasicObject
  end

  # On 1.8.7, Object.ancestors.last == Kernel but
  # things blow up if we include `RSpec::Mocks::Methods`
  # into Kernel...not sure why.
  return Object unless defined?(::BasicObject)

  # MacRuby has BasicObject but it's not the root class.
  return Object unless Object.ancestors.last == ::BasicObject

  ::BasicObject
end

.disable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Disables the expect syntax (expect(dbl).to receive, allow(dbl).to receive, etc).



139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/rspec/mocks/syntax.rb', line 139

def self.disable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
  return unless expect_enabled?(syntax_host)

  syntax_host.class_eval do
    undef receive
    undef allow
    undef expect_any_instance_of
    undef allow_any_instance_of
  end

  RSpec::Mocks::ExampleMethods::ExpectHost.class_eval do
    undef expect
  end
end

.disable_should(syntax_host = default_should_syntax_host) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Disables the should syntax (dbl.stub, dbl.should_receive, etc).



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rspec/mocks/syntax.rb', line 86

def self.disable_should(syntax_host = default_should_syntax_host)
  return unless should_enabled?(syntax_host)

  syntax_host.class_eval do
    undef should_receive
    undef should_not_receive
    undef stub
    undef unstub
    undef stub!
    undef unstub!
    undef stub_chain
    undef as_null_object
    undef null_object?
    undef received_message?
  end

  Class.class_eval do
    undef any_instance
  end
end

.enable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Enables the expect syntax (expect(dbl).to receive, allow(dbl).to receive, etc).



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
# File 'lib/rspec/mocks/syntax.rb', line 109

def self.enable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
  return if expect_enabled?(syntax_host)

  syntax_host.class_eval do
    def receive(method_name, &block)
      Matchers::Receive.new(method_name, block)
    end

    def allow(target)
      AllowanceTarget.new(target)
    end

    def expect_any_instance_of(klass)
      AnyInstanceExpectationTarget.new(klass)
    end

    def allow_any_instance_of(klass)
      AnyInstanceAllowanceTarget.new(klass)
    end
  end

  RSpec::Mocks::ExampleMethods::ExpectHost.class_eval do
    def expect(target)
      ExpectationTarget.new(target)
    end
  end
end

.enable_should(syntax_host = default_should_syntax_host) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Enables the should syntax (dbl.stub, dbl.should_receive, etc).



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
# File 'lib/rspec/mocks/syntax.rb', line 25

def self.enable_should(syntax_host = default_should_syntax_host)
  return if should_enabled?(syntax_host)

  syntax_host.class_eval do
    def should_receive(message, opts={}, &block)
      opts[:expected_from] ||= CallerFilter.first_non_rspec_line
      ::RSpec::Mocks.expect_message(self, message.to_sym, opts, &block)
    end

    def should_not_receive(message, &block)
      opts = { :expected_from => CallerFilter.first_non_rspec_line }
      ::RSpec::Mocks.expect_message(self, message.to_sym, opts, &block).never
    end

    def stub(message_or_hash, opts={}, &block)
      ::RSpec::Mocks::Syntax.stub_object(self, message_or_hash, opts, &block)
    end

    def unstub(message)
      ::RSpec::Mocks.space.proxy_for(self).remove_stub(message)
    end

    def stub!(message_or_hash, opts={}, &block)
      ::RSpec.deprecate "stub!", :replacement => "stub"
      ::RSpec::Mocks::Syntax.stub_object(self, message_or_hash, opts, &block)
    end

    def unstub!(message)
      ::RSpec.deprecate "unstub!", :replacement => "unstub"
      unstub(message)
    end

    def stub_chain(*chain, &blk)
      ::RSpec::Mocks::StubChain.stub_chain_on(self, *chain, &blk)
    end

    def as_null_object
      @_null_object = true
      ::RSpec::Mocks.proxy_for(self).as_null_object
    end

    def null_object?
      defined?(@_null_object)
    end

    def received_message?(message, *args, &block)
      ::RSpec::Mocks.proxy_for(self).received_message?(message, *args, &block)
    end

    unless Class.respond_to? :any_instance
      Class.class_eval do
        def any_instance
          ::RSpec::Mocks.any_instance_recorder_for(self)
        end
      end
    end
  end
end

.expect_enabled?(syntax_host = ::RSpec::Mocks::ExampleMethods) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Indicates whether or not the expect syntax is enabled.

Returns:

  • (Boolean)


162
163
164
# File 'lib/rspec/mocks/syntax.rb', line 162

def self.expect_enabled?(syntax_host = ::RSpec::Mocks::ExampleMethods)
  syntax_host.method_defined?(:allow)
end

.should_enabled?(syntax_host = default_should_syntax_host) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Indicates whether or not the should syntax is enabled.

Returns:

  • (Boolean)


156
157
158
# File 'lib/rspec/mocks/syntax.rb', line 156

def self.should_enabled?(syntax_host = default_should_syntax_host)
  syntax_host.method_defined?(:should_receive)
end

.stub_object(object, message_or_hash, opts = {}, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Common stubbing logic for both stub and stub!. This used to live in stub, and stub! delegated to stub, but we discovered that stub! was delegating to RSpec::Mocks::ExampleMethods#stub (which declares a test double) when called with an implicit receiver, which was a regression in 2.14.0.



14
15
16
17
18
19
20
21
# File 'lib/rspec/mocks/syntax.rb', line 14

def self.stub_object(object, message_or_hash, opts = {}, &block)
  if ::Hash === message_or_hash
    message_or_hash.each {|message, value| stub_object(object, message).and_return value }
  else
    opts[:expected_from] = CallerFilter.first_non_rspec_line
    ::RSpec::Mocks.allow_message(object, message_or_hash, opts, &block)
  end
end

Instance Method Details

#allowObject

Note:

This is only available when you have enabled the expect syntax.

Used to wrap an object in preparation for stubbing a method on it.

Examples:


allow(dbl).to receive(:foo).with(5).and_return(:return_value)


# File 'lib/rspec/mocks/syntax.rb', line 304

#allow_any_instance_ofObject

Note:

This is only available when you have enabled the expect syntax.

Used to wrap a class in preparation for stubbing a method on instances of it.

Examples:


allow_any_instance_of(MyClass).to receive(:foo)


# File 'lib/rspec/mocks/syntax.rb', line 324

#any_instanceRecorder

Note:

This is only available when you have enabled the should syntax.

Used to set stubs and message expectations on any instance of a given class. Returns a Recorder, which records messages like stub and should_receive for later playback on instances of the class.

Examples:


Car.any_instance.should_receive(:go)
race = Race.new
race.cars << Car.new
race.go # assuming this delegates to all of its cars
        # this example would pass

Account.any_instance.stub(:balance) { Money.new(:USD, 25) }
Account.new.balance # => Money.new(:USD, 25))

Returns:

  • (Recorder)


# File 'lib/rspec/mocks/syntax.rb', line 271

#as_null_objectObject

Note:

This is only available when you have enabled the should syntax.

Tells the object to respond to all messages. If specific stub values are declared, they'll work as expected. If not, the receiver is returned.



# File 'lib/rspec/mocks/syntax.rb', line 259

#expectObject

Note:

This method is usually provided by rspec-expectations, unless you are using rspec-mocks w/o rspec-expectations, in which case it is only made available if you enable the expect syntax.

Used to wrap an object in preparation for setting a mock expectation on it.

Examples:


expect(obj).to receive(:foo).with(5).and_return(:return_value)


# File 'lib/rspec/mocks/syntax.rb', line 292

#expect_any_instance_ofObject

Note:

This is only available when you have enabled the expect syntax.

Used to wrap a class in preparation for setting a mock expectation on instances of it.

Examples:


expect_any_instance_of(MyClass).to receive(:foo)


# File 'lib/rspec/mocks/syntax.rb', line 314

#null_object?Object

Note:

This is only available when you have enabled the should syntax.

Returns true if this object has received as_null_object



# File 'lib/rspec/mocks/syntax.rb', line 266

#receiveObject

Note:

This is only available when you have enabled the expect syntax.

Used to specify a message that you expect or allow an object to receive. The object returned by receive supports the same fluent interface that should_receive and stub have always supported, allowing you to constrain the arguments or number of times, and configure how the object should respond to the message.

Examples:


expect(obj).to receive(:hello).with("world").exactly(3).times


# File 'lib/rspec/mocks/syntax.rb', line 334

#should_not_receiveObject

Sets and expectation that this object should not receive a message during this example.



# File 'lib/rspec/mocks/syntax.rb', line 202

#should_receiveObject

Note:

This is only available when you have enabled the should syntax.

Sets an expectation that this object should receive a message before the end of the example.

Examples:


logger = double('logger')
thing_that_logs = ThingThatLogs.new(logger)
logger.should_receive(:log)
thing_that_logs.do_something_that_logs_a_message


# File 'lib/rspec/mocks/syntax.rb', line 189

#stubObject

Note:

This is only available when you have enabled the should syntax.

Tells the object to respond to the message with the specified value.

Examples:


counter.stub(:count).and_return(37)
counter.stub(:count => 37)
counter.stub(:count) { 37 }


# File 'lib/rspec/mocks/syntax.rb', line 206

#stub_chain(method1, method2) ⇒ Object #stub_chain("method1.method2") ⇒ Object #stub_chain(method1, method_to_value_hash) ⇒ Object

Note:

This is only available when you have enabled the should syntax.

Stubs a chain of methods.

Warning:

Chains can be arbitrarily long, which makes it quite painless to violate the Law of Demeter in violent ways, so you should consider any use of stub_chain a code smell. Even though not all code smells indicate real problems (think fluent interfaces), stub_chain still results in brittle examples. For example, if you write foo.stub_chain(:bar, :baz => 37) in a spec and then the implementation calls foo.baz.bar, the stub will not work.

Examples:


double.stub_chain("foo.bar") { :baz }
double.stub_chain(:foo, :bar => :baz)
double.stub_chain(:foo, :bar) { :baz }

# Given any of ^^ these three forms ^^:
double.foo.bar # => :baz

# Common use in Rails/ActiveRecord:
Article.stub_chain("recent.published") { [Article.new] }


# File 'lib/rspec/mocks/syntax.rb', line 228

#unstubObject

Note:

This is only available when you have enabled the should syntax.

Removes a stub. On a double, the object will no longer respond to message. On a real object, the original method (if it exists) is restored.

This is rarely used, but can be useful when a stub is set up during a shared before hook for the common case, but you want to replace it for a special case.



# File 'lib/rspec/mocks/syntax.rb', line 217