From befb416021b08d663b78024e6537680d93c64ac3 Mon Sep 17 00:00:00 2001 From: Thom Carter Date: Mon, 12 Feb 2018 16:50:02 +0000 Subject: [PATCH] Define respond_to_missing? on Mocha::Mock Fixes #321. As of Ruby 2.4, Forwardable warns when delegating to a private method. Warnings are shown when delegating methods to a Mocha::Mock. To determine whether to show a warning, Forwardable tests the delegated method with the defined? operator. Mocha uses method_missing to respond to mocked methods. defined? uses respond_to_missing? to determine whether or not a missing method is defined. Defining respond_to_missing? on Mocha::Mock, in place of respond_to?, prevents warnings from being shown. To preserve compatibility with Ruby 1.8.7, we continue to conditionally define respond_to?. Prior to Ruby 1.9.3, defined? returns nil for method calls handled via method_missing, so we also only test that mocked methods are defined? in later Ruby versions. --- lib/mocha/mock.rb | 10 +++++++++- test/unit/mock_test.rb | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/mocha/mock.rb b/lib/mocha/mock.rb index 69e1bcce1..c35c4256c 100644 --- a/lib/mocha/mock.rb +++ b/lib/mocha/mock.rb @@ -9,6 +9,7 @@ require 'mocha/argument_iterator' require 'mocha/expectation_error_factory' require 'mocha/deprecation' +require 'mocha/ruby_version' module Mocha @@ -314,7 +315,7 @@ def method_missing(symbol, *arguments, &block) end # @private - def respond_to?(symbol, include_private = false) + def respond_to_missing?(symbol, include_private = false) if @responder then if @responder.method(:respond_to?).arity > 1 @responder.respond_to?(symbol, include_private) @@ -326,6 +327,13 @@ def respond_to?(symbol, include_private = false) end end + # @private + if PRE_RUBY_V19 + def respond_to?(symbol, include_private = false) + respond_to_missing?(symbol, include_private) + end + end + # @private def __verified__?(assertion_counter = nil) @expectations.verified?(assertion_counter) diff --git a/test/unit/mock_test.rb b/test/unit/mock_test.rb index 7dc02e18a..44cce4868 100644 --- a/test/unit/mock_test.rb +++ b/test/unit/mock_test.rb @@ -334,6 +334,14 @@ def test_should_remove_expectation_for_unstubbed_method assert_match(/unexpected invocation/, e.message) end + unless PRE_RUBY_V19 + def test_expectation_is_defined_on_mock + mock = build_mock + mock.expects(:method1) + assert defined? mock.method1 + end + end + private def build_mock