Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Handle additional any_instance / and_call_original edge cases.

For #197.
  • Loading branch information...
commit 148db3c200a88db1987913ca92c7b3db35a5b518 1 parent d2ef056
@myronmarston myronmarston authored
View
8 lib/rspec/mocks/any_instance/recorder.rb
@@ -113,6 +113,10 @@ def build_alias_method_name(method_name)
"__#{method_name}_without_any_instance__"
end
+ def already_observing?(method_name)
+ @observed_methods.include?(method_name)
+ end
+
private
def normalize_chain(*args)
@@ -165,10 +169,6 @@ def stop_observing!(method_name)
@observed_methods.delete(method_name)
end
- def already_observing?(method_name)
- @observed_methods.include?(method_name)
- end
-
def observe!(method_name)
stop_observing!(method_name) if already_observing?(method_name)
@observed_methods << method_name
View
9 lib/rspec/mocks/method_double.rb
@@ -85,11 +85,18 @@ def original_method
end
def original_unrecorded_any_instance_method
+ return nil unless any_instance_class_recorder_observing_method?(@object.class)
alias_name = @object.class.__recorder.build_alias_method_name(@method_name)
- return nil unless @object.respond_to?(alias_name)
@object.method(alias_name)
end
+ def any_instance_class_recorder_observing_method?(klass)
+ return true if klass.__recorder.already_observing?(@method_name)
+ superklass = klass.superclass
+ return false if superklass.nil?
+ any_instance_class_recorder_observing_method?(superklass)
+ end
+
if RUBY_VERSION.to_f > 1.8
# @private
def original_method_from_superclass
View
31 spec/rspec/mocks/and_call_original_spec.rb
@@ -37,9 +37,22 @@ def instance.foo; :bar; end
expect(instance.foo).to eq(:bar)
end
- it 'works for an any_instance partial mock' do
- klass.any_instance.should_receive(:meth_1).and_call_original
- expect(klass.new.meth_1).to eq(:original)
+ context 'when using any_instance' do
+ it 'works for instance methods defined on the class' do
+ klass.any_instance.should_receive(:meth_1).and_call_original
+ expect(klass.new.meth_1).to eq(:original)
+ end
+
+ it 'works for instance methods defined on the superclass of the class' do
+ subclass = Class.new(klass)
+ subclass.any_instance.should_receive(:meth_1).and_call_original
+ expect(subclass.new.meth_1).to eq(:original)
+ end
+
+ it 'works when mocking the method on one class and calling the method on an instance of a subclass' do
+ klass.any_instance.should_receive(:meth_1).and_call_original
+ expect(Class.new(klass).new.meth_1).to eq(:original)
+ end
end
if RUBY_VERSION.to_f > 1.8
@@ -103,6 +116,18 @@ def method_missing(name, *args)
expect(instance.greet_jack).to eq("Hello, jack")
end
+ it 'works for an any_instance partial mock' do
+ klass.any_instance.should_receive(:greet_jack).and_call_original
+ expect(instance.greet_jack).to eq("Hello, jack")
+ end
+
+ it 'raises an error for an unhandled message for an any_instance partial mock' do
+ klass.any_instance.should_receive(:not_a_handled_message).and_call_original
+ expect {
+ instance.not_a_handled_message
+ }.to raise_error(NameError, /not_a_handled_message/)
+ end
+
it 'raises an error on invocation if method_missing does not handle the message' do
instance.should_receive(:not_a_handled_message).and_call_original

0 comments on commit 148db3c

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