2012-12-12 23 views
7

在結構體上使用rspec double會有什麼優點和缺點?例如ruby​​中的struct vs test double

before :each do 
    location = double "locatoin" 
    location.stub(:id => 1) 
end 

VS

before :each do 
    location = Struct.new("locatoin", :id) 
    location.new.id = 1 
end 

回答

8

測試雙打更容易建立

Slip = Struct.new(:id) 
slip = Slip.new(:id => 1) 

slip = double('slip', :id => 1) 

個測試雙打產生更有意義的錯誤消息

require 'spec_helper' 

class TooLongError < StandardError; end 

class Boat 
    def moor(slip) 
    slip.moor!(self) 
    rescue TooLongError 
    false 
    end 
end 

describe Boat do 
    let(:boat) { subject } 

    context "when slip won't accept boat" do 
    it "can't be moored" do 
     Slip = Struct.new('Slip') 
     slip = Slip.new 
     boat.moor(slip).should be_false 
    end 
    end 
end 
Failure/Error: slip.moor!(self) 
NoMethodError: 
    undefined method `moor!' for #<struct Struct::Slip > 

it "can't be moored" do 
    slip = double('slip') 
    boat.moor(slip).should be_false 
end 
Failure/Error: slip.moor!(self) 
    Double "slip" received unexpected message :moor! with (#<Boat:0x106b90c60>) 

測試雙打有測試更好的支持

class Boat 
    def moor(slip) 
    slip.dont_care 
    slip.moor!(self) 
    rescue TooLongError 
    false 
    end 
end 

it "can't be moored" do 
    Slip = Struct.new('Slip') 
    slip = Slip.new 
    slip.should_receive(:moor!).and_raise(TooLongError) 
    boat.moor(slip).should be_false 
end 
Failure/Error: slip.dont_care 
NoMethodError: 
    undefined method `dont_care' for #<struct Struct::Slip > 

it "can't be moored" do 
    slip = double('slip').as_null_object 
    slip.should_receive(:moor!).and_raise(TooLongError) 
    boat.moor(slip).should be_false 
end 

0 failures # passed!

這幾個例子 - 我肯定有更多的理由更喜歡測試雙打。

+0

我知道這是自上次發佈以來的幾年,但有沒有可能您不介意更改示例?我不知道與船隻有什麼聯繫或滑落,這讓我很難嘗試弄清楚事情的真相。如果沒有,反正謝謝! – SirUncleCid