[rspec-users] Speccing private class methods
work at ashleymoran.me.uk
Thu Dec 21 10:16:24 EST 2006
On 21 Dec 2006, at 12:59, David Chelimsky wrote:
> In theory you shouldn't be specifying anything about private methods.
Here is my original thinking:
- I've written a method somewhere (private or otherwise) that is
- I know the algorithm must use this method to behave correctly
- therefore I should specify that the main method calls the
Not testing the private methods seems to increase the granularity of
the specs too much. There's a lot of stuff we do has complex but
decomposable algorithms, and it makes sense to test the parts of
these even if they are not part of the public interface. Not doing
so seems similar to not unit testing ActiveRecord models because you
can test their behaviour in the controller specs (which is what Rails
does with Test::Unit)
> The only reason we support partial mocks at all (which is a mocking
> no-no) is because Rails forces us to.
Why is this so wrong and what about about Rails forces it? I'm new
to mocking and I'm not sure I'm clear on the definition. (Does the
following code count as partial mocking, seeing how "date" is
required in the CapFutureResidual model class file?)
Here is a spec I wrote today that tests a really simple (private)
context "CapFutureResidual.registration_date_recent?" do
Date.stub!(:today).and_return(Date.new(2006, 12, 20))
specify "should find the current date" do
(2006, 12, 20))
(2006, 06, 25))
specify "should define a data under six months old (approx) as
(2006, 06, 23)).should == true
specify "should define a date over six months old (approx) as not
(2006, 06, 22)).should == false
Again, I don't see how specifying Date.should_receive(:today) is
different from specifying that a private method is called, or should
I not be doing this either...
> You won't find a solution to your problem within RSpec, but you can
> do this:
> specify "(2) call_private_method should call private_method" do
> MyClass.send :public, 'private_method'
> MyClass.should_receive(:private_method).and_return("this is
> MyClass.send :private, 'private_method'
> So, for this spec only, you can access the method to spec that it gets
> called, but then restore the method to its private state.
Hmmm... not sure if I'd like to write specs like this... might just
drop that spec entirely and include the behaviour of the private
method in the spec for the calling method.
More information about the rspec-users