How to intercept an instance method from StdLib (1.9.2)

Hi,
I’m struggling with something that seems to be simple, and I’ve not
had any joy following the RSpec books suggestions (p. 187).
I’d like to test that a method raises and error when a file is not
found.
I’ve tried adding this in my example just before I call my method, but
it never seems to get invoked.
Pathname.stub(:exist?).and_return(false)

The whole example:

it "should raise an error if RVM's install root does not exist" do
   Pathname.stub(:exist?).and_return(false)
   lambda{ B3::Bdd::Helpers.rvm_path}.should

raise_error(RuntimeError, “File not found:”)
end

Appreciate any tips.


πόλλ’ οἶδ ἀλώπηξ, ἀλλ’ ἐχῖνος ἓν μέγα
[The fox knows many things, but the hedgehog knows one big thing.]
Archilochus, Greek poet (c. 680 BC – c. 645 BC)
http://wiki.hedgehogshiatus.com

On 4 Mar 2011, at 05:45, Hedge H. wrote:

Hi,
I’m struggling with something that seems to be simple, and I’ve not
had any joy following the RSpec books suggestions (p. 187).
I’d like to test that a method raises and error when a file is not found.
I’ve tried adding this in my example just before I call my method, but
it never seems to get invoked.
Pathname.stub(:exist?).and_return(false)

That’s stubbing a class method.

exist? is an instance method so you need to stub the specific instance
of pathname that’s being used in your object-under-test, rather than the
Pathname class.


πόλλ’ οἶδ ἀλώπηξ, ἀλλ’ ἐχῖνος ἓν μέγα
[The fox knows many things, but the hedgehog knows one big thing.]
Archilochus, Greek poet (c. 680 BC – c. 645 BC)
http://wiki.hedgehogshiatus.com


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

cheers,
Matt

[email protected]
07974 430184

On Fri, Mar 4, 2011 at 8:12 PM, Matt W. [email protected] wrote:

That’s stubbing a class method.

exist? is an instance method so you need to stub the specific instance of
pathname that’s being used in your object-under-test, rather than the Pathname
class.

Is there a (clean) way to intercept this instance and add the
stub/mock to it? What I see in the Rspec books suggests I’d have to
force the Pathname instance to the surface, as some method argument.
That feels all wrong - to have to change my method’s interface just to
test a behavior.

Appreciate any experience, comments or suggestions people may have.

cheers,
Matt

[email protected]
07974 430184


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users


πόλλ’ οἶδ ἀλώπηξ, ἀλλ’ ἐχῖνος ἓν μέγα
[The fox knows many things, but the hedgehog knows one big thing.]
Archilochus, Greek poet (c. 680 BC – c. 645 BC)
http://wiki.hedgehogshiatus.com

On 5 Mar 2011, at 12:06, Hedge H. wrote:

Pathname.stub(:exist?).and_return(false)
test a behavior.

Appreciate any experience, comments or suggestions people may have.

You could try something like this:

fake_pathname = double(Pathname, :exist? => false)
Pathname.stub(:new).and_return(fake_pathname)

This is basically The Ruby Way of doing dependency injection.

Appreciate any tips.

http://rubyforge.org/mailman/listinfo/rspec-users
cheers,
Matt

[email protected]
07974 430184

On 6 Mar 2011, at 10:30, Hedge H. wrote:

had any joy following the RSpec books suggestions (p. 187).
Is there a (clean) way to intercept this instance and add the
Pathname.stub(:new).and_return(fake_pathname)
TIA
In the Java / C# world, I’d be more used having to do something like
this:

fake_pathname = double(Pathname, :exist? => false)
helper = B3::Bdd::Helpers.new(fake_pathname)

or even

fake_pathname = double(Pathname, :exist? => false)
fake_pathanme_factory = double("PathnameFactory", :new => 

fake_pathname)
helper = B3::Bdd::Helpers.new(fake_pathname_factory)

Fortunately, this kind of thing just isn’t necessary in Ruby.

The risk of doing what I’ve suggested above is that there are probably
other legitimate ways of instantiating a Pathname (I don’t know what
they are, but I can imagine there could be some) and you might one day
want to refactor your tested class to use one of those alternative ways.
If you did, your test would break for no good reason, just because you
were no longer hitting Pathname.new and so the stubs stopped working.
However, .new is pretty idiomatic in Ruby, so you’re normally safe.

end
[email protected]
[email protected]
rspec-users mailing list
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users


πόλλ’ οἶδ ἀλώπηξ, ἀλλ’ ἐχῖνος ἓν μέγα
[The fox knows many things, but the hedgehog knows one big thing.]
Archilochus, Greek poet (c. 680 BC – c. 645 BC)
http://wiki.hedgehogshiatus.com

cheers,
Matt

[email protected]
07974 430184

On Sun, Mar 6, 2011 at 12:27 AM, Matt W. [email protected] wrote:

I’d like to test that a method raises and error when a file is not found.
stub/mock to it? What I see in the Rspec books suggests I’d have to

This is basically The Ruby Way of doing dependency injection.

Thank you Matt. Not sure if I’m going mad but it seems the Rspec
book, Ch 14, doesn’t cover this use case in much detail.
I appreciate it is an introductory book, so this may be out of scope.
Alternatively: It may be that, reaching inside a method in this way is
a ‘test-smell’ indicating some bad practice - I’m I being too
sensitive?

TIA

http://rubyforge.org/mailman/listinfo/rspec-users
http://rubyforge.org/mailman/listinfo/rspec-users
[email protected]
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users


πόλλ’ οἶδ ἀλώπηξ, ἀλλ’ ἐχῖνος ἓν μέγα
[The fox knows many things, but the hedgehog knows one big thing.]
Archilochus, Greek poet (c. 680 BC – c. 645 BC)
http://wiki.hedgehogshiatus.com