freerange/mocha — pull request #142 by burns (2013-03-02 19:53:38+00:00)
Title: visibility can not be set for methods that do not exist

This occurs under 1.8.7 when alias method names are defined as module_functions, as FileUtils does.
When these methods are unstubbed and `remove_method` is called, the method no longer exists.
Since the `@original_method.owner` does not match the `stubbee.__metaclass__`, no method is restored.
This causes the attempt to set visibility to raise an exception.

Not only can these methods not be unstubbed, but if they are stubbed, `mocha_teardown` will attempt
to unstub them and cause this exception to be raised as well.

I was unable to create a failing test for this in mocha's acceptance tests. For some reason, the
method still exists after `remove_method` is called.

However, the following test will show the failure.

```rb
require 'test/unit'
require 'mocha/setup'

class TestStubbing < Test::Unit::TestCase
def test_stubbing
mod = Module.new do
def my_module_method; :original_return_value; end
module_function :my_module_method
alias my_alias_method my_module_method
module_function :my_alias_method
end

mod.stubs(:my_alias_method).returns(:new_return_value)
assert_equal :new_return_value, mod.my_alias_method

# will raise an exception with or without this call due to `mocha_teardown`
mod.unstub(:my_alias_method)
end
end
```
The same occurs using MiniTest or RSpec w/mocha.

The exception raised here is somewhat deceiving, as it's the result of the `mocha_teardown`.

```
lib/mocha/class_method.rb:71:in `remove_method': method `my_alias_method' not defined in Module
```

If you leave out the call to `mod.unstub` in the test, `mocha_teardown` will attempt to unstub it
and you'll get the initial exception, which is:

```
mocha/class_method.rb:89:in `public': undefined method `my_alias_method' for class `Module'
```