2012-03-19 11 views
2

は、このクラスを考える:この単純なRSpec文字列同値仕様が失敗するのはなぜですか?

class First 
    def to_s ; "Hello World" ; end 
end 

と、このスペック:

require 'first' 

describe First do 
    describe "#to_s" do 
    it { should == "Hello World" } 
    end 
end 

私が手:

Failures: 

    1) First#to_s 
    Failure/Error: it { should == "Hello World" } 
     expected: "Hello World" 
      got: Hello World (using ==) 
     Diff: 
     @@ -1,2 +1,2 @@ 
     -"Hello World" 
     +Hello World 
    # ./spec/first_spec.rb:5:in `block (3 levels) in <top (required)>' 

しかし、私はこれが通過するのを期待します。私の質問は次のとおりです:

  • どのような通過スペックはどのように見えますか?
  • なぜこの仕様は合格しませんか?
+0

railsタグについて:実際にはRails固有のトピックではないので、私はそこに配置しませんでした。しかし、私はそれらを削除しないでしょう。なぜなら、おそらくトピックに興味のある人々の80%がRailsの開発者だからです。 –

答えて

4

あなたの外側describeブロック:

describe First do 

は、内部の例の件名をto be an instance ofFirstに設定します。つまり、あなたが記述しているitはすべてFirstオブジェクトになります。テキスト#to_sの例では、rspecにオブジェクトのto_sを呼び出すよう指示していません。

First.new"Hello World"と等しくないので、仕様は失敗します。

しかし、rspecはオブジェクト上でto_sを呼び出して失敗の説明で出力するため、そこに「Hello World」と表示されます。

its(:to_s) { should == "Hello World" } 
+0

非常に興味深い点、感謝と+1 – apneadiving

+0

ありがとうございます@ガレスと@スナイプ!私はこれを好むが、2つの非常に良い答え。要約すると、** Q1、 "How ...?" ** - 私が意図した合格スペックは 'its'(答えの例を参照)を使用し、内部の' describe'レベルを取り除くことができます。 ** Q2、 "なぜ...?" ** - 私は '記述' #blah "を使って"被写体を設定すると思ったが、そうではない。代わりに、主題はまだ「First.new」です。 –

2

私は#method_nameを使って、結果を自動的に評価することはありませんでした。私は何をしているのかを冗長にすることをお勧めします。

一般的に、私はこれらの中からいずれかを選択:

describe First do 
    specify { First.new.to_s.should == "Hello World" } 
end 

または:

describe First do 
    describe "#to_s" do 
    subject { First.new.to_s } 
    it { should == "Hello World" } 
    end 
end 

または:

describe First do 
    describe "#to_s" do 
    let(:result) { First.new.to_s } 
    specify { result.should == "Hello World" } 
    end 
end