2013-01-08 32 views
0

我想主張在一個數組包含的元素類,我嘗試以下方法:需要用rspec來匹配元素類的數組嗎?

這並不工作,但它看起來不錯,可讀:

["String", :symbol, Object.new].should =~ [an_instance_of(String), an_instance_of(Symbol), an_instance_of(Object)] 

,但給了我下面的錯誤:

Failure/Error: ["String", :symbol, Object.new].should =~ [an_instance_of(String), an_instance_of(Symbol), an_instance_of(Object)] 
    expected collection contained: [#<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33dbe0 @klass=String>, #<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33dbb8 @klass=Symbol>, #<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33db68 @klass=Object>] 
    actual collection contained: ["String", :symbol, #<Object:0x007f9e6a33dca8>] 
    the extra elements were:  ["String", :symbol, #<Object:0x007f9e6a33dca8>] 

請注意,沒有缺失元素。

這工作,但看起來哈克:

["String", :symbol, Object.new].collect{|x| x.class}.should =~ [String, Symbol,Object] 
  1. 有沒有更好的方式來主張是一回事嗎?
  2. 爲什麼沒有缺失元素的第一種方式?

回答

3

你可以使用&:class,而不是塊,

["String",:symbol,Object.new].map(&:class).should =~ [String,Symbol,Object] 

這將產生相同的,但更具有可讀性。

此外,我使用map這是collect方法的簡短別名。

+0

不錯..好多了:) 但這隻能回答第一個問題。 –

+0

你應該接受你最喜歡的答案! – akuhn

2

第二部分的答案取決於您的說法「請注意,沒有缺失的元素。」有缺失的元素。

此:

expected collection contained: [#<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33dbe0 @klass=String>, #<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33dbb8 @klass=Symbol>, #<RSpec::Mocks::ArgumentMatchers::InstanceOf:0x007f9e6a33db68 @klass=Object>] 

是不一樣的,因爲這:

the extra elements were:  ["String", :symbol, #<Object:0x007f9e6a33dca8>] 

第一個包含一個類的實例的模擬對象,第二個包含的類的實例。匹配器不應該以這種方式使用,你會這樣做嗎?

["String", :symbol, Object.new].should =~ [respond_to(:gsub), respond_to(:intern), respond_to(:object_id)] 

這是沒有意義的,因爲你要麼被測試陣列,每個陣列的內容具有某種屬性的。你所做的就是混淆這兩個測試,並且這樣做會導致兩個問題。

subject { instance } 
["String", :symbol, Object.new].each do |thing| 
    let(:instance) { thing.class } 
    if instance.class == String 
     it{ should respond_to(:gsub) } 
    else #... 

更多的東西一樣,但我覺得這是一個代碼/設計氣味無論如何 - 爲什麼你會在同一陣列中有這樣的不同的東西?規範,測試和處理很困難。