Em 25-04-2011 14:58, Matthew Van Horn escreveu:

On Apr 25, 2011, at 1:36 PM, Matthew Van Horn wrote:

I've run into some strange behavior in porting my specs from rspec to rspec2. I am wondering if I am doing something wrong, or if I've misunderstood something, or if this is some kind of bug.

Look at the specs below: a
Both examples will pass if run singly.
The second one will fail if I run both examples.

Can someone tell me why the second one fails the way it does?

It has to do with the conditional assignment of @my_foo, but I'm not sure why @stupid_mock is getting disconnected. My thinking is that the class Bar is returning the same object in both tests, and that the stub call in the second test is being sent to a different object.

Still, it did not behave this way in the last version, so I don't know what I'm missing.

require 'spec_helper'

class Foo
end

class Bar
  def self.my_foo
    @my_foo ||= Foo.new
  end
  def self.perform
    my_foo.do_something
  end
end

describe Foo do

  before(:each) do
    @stupid_mock = double('wtf')
    Foo.stub(:new => @stupid_mock)
  end
  it "passes here" do
    @stupid_mock.should_receive(:do_something).and_return('value')
    Bar.perform
  end
  it "fails here" do
    @stupid_mock.stub(:do_something => 'value')
    Bar.perform
# double "wtf" received unexpected message :do_something with (no args)
  end
end

btw - I just realized, that should be: "describe *Bar* do"
and, I can solve the problem by doing: Bar.stub(:my_foo => @stupid_mock) instead of Foo.stub(:new => @stupid_mock) but I really don't like stubbing methods on the class I am testing.


The problem is that "new" is not a regular method on Ruby. I don't mind mocking some methods of the class being tested in some cases.

For instance, I have a class that does lots of calculation based on numerous input data. It would be impossible to provide all possible combinations of input data for testing the calculation of some methods.

Consider the following class:

class InterestingCalculator
    include Singleton
    def a
        @a ||= hard_calculation_based_on(@several_inputs)
    end

    def b
        return 0 if a < 0
        calculate_using a
    end
end

Then I would write something like:

describe InterestingCalculator do
  example "b should be 0 when a < 0" do
    InterestingCalculator.instance.stub!(:a).and_return(-10)
    InterestingCalculator.instance.b.should == 0
  end

  example "b should do something great when a >= 0" do
    InterestingCalculator.instance.stub!(:a).and_return(10)
    InterestingCalculator.instance.b.should == 786
  end
end

At least, this makes sense to me...

Best regards,

Rodrigo.
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to