簡體   English   中英

Ruby在Rspec中檢查vs to_s

[英]Ruby inspect vs to_s in Rspec

考慮對rspec進行以下測試:

class RspecTest
  def initialize
  end

  def to_s
    "foo"
  end
end

describe RspecTest do
  it "should return foo (to_s)" do
    RspecTest.new.should == "foo"
  end

  it "should return foo (inspect)" do
    RspecTest.new.inspect == "foo"
  end
end

當通過rspec測試時:

%: rspec rspec_test.rb 
F.

Failures:

  1) RspecTest should return foo (to_s)
     Failure/Error: RspecTest.new.should == "foo"
       expected: "foo"
            got: foo (using ==)
       Diff:
     # ./rspec_test.rb:13:in `block (2 levels) in <top (required)>'

Finished in 0.00059 seconds
2 examples, 1 failure

因此,第一個測試失敗,而第二個測試通過。 這是為什么?

第二個測試通過了,因為它沒有測試任何東西。 它不包含任何期望(即,對shouldshould_not的調用)。 不會失敗,因為沒有什么可以失敗的。

第一次測試失敗,因為您斷言RspecTest的實例等於字符串'foo' 這不可能是真的。 如果這兩個對象不是同一種對象,怎么可能相等?

從測試的描述來看,您實際上並不是要測試RspecTest的實例是否等於字符串'foo' ,而是要測試實例方法to_s的返回值是否等於字符串'foo' 但是,您永遠不會在任何地方調用to_s

讓我們首先解決兩個明顯的問題。 現在,我們進行如下測試:

it 'should return foo (to_s)' do
  RspecTest.new.to_s.should == 'foo'
end

it 'should return foo (inspect)' do
  RspecTest.new.inspect.should == 'foo'
end

這兩個RspecTest.new調用之間存在一些不必要的重復,因此讓我們通過簡單地將RspecTest.new為默認主題來解決此問題:

  subject { RspecTest.new }

  it 'should return foo (to_s)' do
    subject.to_s.should == 'foo'
  end

  it 'should return foo (inspect)' do
    subject.inspect.should == 'foo'
  end

實際上,如果您不提供明確的主題,則RSpec將沿着嵌套的describe塊的鏈向上移動,直到找到一個類為止,並且將僅調用該類的new方法來提供主題。 因此,我們可以刪除subject聲明:

  it 'should return foo (to_s)' do
    subject.to_s.should == 'foo'
  end

  it 'should return foo (inspect)' do
    subject.inspect.should == 'foo'
  end

就個人而言,我更喜歡讓RSpec自己提供示例名稱,以免示例名稱和實際示例代碼不同步,因此,我可能會這樣寫:

describe RspecTest do
  describe '#to_s' do
    it { subject.to_s.should == 'foo' }
  end

  describe '#inspect' do
    it { subject.inspect.should == "foo" }
  end
end

產生:

RspecTest
  #to_s
    should == "foo"
  #inspect
    should == "foo"

Finished in 0.16023 seconds
2 examples, 0 failures

最后但並非最不重要的一點是,您的初始化程序實際上並未執行任何操作,因此您不需要它。 總之,我的版本如下所示:

class RspecTest
  def to_s; 'foo' end
end

describe RspecTest do
  describe '#to_s' do
    it { subject.to_s.should == 'foo' }
  end

  describe '#inspect' do
    it { subject.inspect.should == "foo" }
  end
end

我認為您的測試應如下(它們都將通過)。 第一個缺少實際的to_s調用,第二個缺少.should

describe RspecTest do
  it "should return foo (to_s)" do
    RspecTest.new.to_s.should == "foo"
  end

  it "should return foo (inspect)" do
    RspecTest.new.inspect.should == "foo"
  end
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM