0

'Weight converter'

Trying to get the hang of using stubs but I can't get the format right, what do I have wrong? I know I already have the method in the code in this case but I am trying to learn how to do a stub correctly.

Test:

describe "Convert Pounds to Kilograms" do

it "should convert 3lb to 1kg" do
  weight = WeightConverter.stub!(:convert).with(3, 'lbs_to_kgs').and_return(1)
  weight.should == 1
end

Code:

class WeightConverter

  def self.convert(from, what_to_what)
    if what_to_what == 'lbs_to_kgs'
      (from / 2.2).truncate
    elsif what_to_what == 'kgs_to_lbs'
      (from * 2.2).truncate
    end
  end
end

fyi - this works (without stubs)

  it "should convert 91lbs to 41kgs" do
    weight = WeightConverter.convert(91, 'lbs_to_kgs')
    weight.should == 41
  end

Error:

Failures:

 1) Convert Pounds to Kilograms should convert 3lb to 1kg
     Failure/Error: weight.should == 1
       expected: 1
            got: #<Proc:0x000000010b0468@/home/durrantm/.rvm/gems/ruby-1.9.3-p125/gems/rspec-mocks-2.10.1/lib/rspec/mocks/message_expectation.rb:459 (lambda)> (using ==)
     # ./weight_converter_spec.rb:19:in `block (2 levels) in <top (required)>'

Finished in 0.00513 seconds
7 examples, 1 failure
Jens Björnhager
  • 5,632
  • 3
  • 27
  • 47
junky
  • 1,480
  • 1
  • 17
  • 32

1 Answers1

2

You don't want to assign to the stub, rather you should be doing something like this:

it "should convert 3lb to 1kg" do
  WeightConverter.stub!(:convert).with(3, 'lbs_to_kgs').and_return(1)
  weight = WeightConverter.convert(3, 'lbs_to_kgs')
  weight.should == 1
end

However, that's a fairly useless test -- the only thing it's testing is that your stub/mock library does what it's supposed to (i.e. it's not actually testing WeightConverter at all). Since you're directly testing the internals of WeightConverter, you don't need to stub it. You should be using actual values like in your second example. However, if WeightConverter depended on another class, you might stub that other class.

Dylan Markow
  • 123,080
  • 26
  • 284
  • 201
  • Yes it's for learning purposes on how to do stubs, I'm pretending the method doesn't yet exist and that in reality I would do 'other stuff' not just check this return value. So given that having the actual WeightConverter.convert method is something I wanted to avoid at this point. – junky May 13 '12 at 23:54
  • Yes, then the code I gave you should work for that -- it'll never actually call `WeightConverter.convert` since it'll just use the stub instead. – Dylan Markow May 13 '12 at 23:55
  • Ah, so once you define that method as being stubbed, then when you call it (the actual method), the call uses the stubbed method? So it's always a 2 step process then? – junky May 13 '12 at 23:59
  • Well again, usually you would be stubbing it, but not calling it directly in the same test. If you're testing class A which depends on class B, you may stub out something in class B. Then, when you test class A, it won't actually use class B, it'll just use your stubbed method. – Dylan Markow May 14 '12 at 00:14