2011-11-06 36 views
3

这是我的。那种工作。更好的方法来断言用户数组中的所有user.name都以使用rspec的前缀开头?

it "should filter by name" do 
    users = users.search(:name => "s") 
    users.each {|u| 
    u.name.should be_starts_with("s") 
    } 
end 

然而,由rspec的返回的错误消息是真穷...

expected starts_with?("s") to return true, got false

是否有一种方式来获得更精确的信息,显示出失败的元素,或至少它的索引?

+1

也....我写它“名称过滤器”而不是“应按名称过滤” – coreyhaines

+1

应该be_starts_with只是可怕的读取。 – coreyhaines

+0

真的,感谢您的反馈:)。 –

回答

20

在这样的二进制测试中,我会创建两个用户,一个以s开头,另一个没有。然后我会检查是否只有预期的元素被返回。

set up a user(:name => "Sam") and user(:name => "Fred") 

filtered_users.map(&:name).should =~ ["Sam"] 

在出现故障的情况下,你会看到类似

expected ["Sam"] 
got ["Fred", "Sam"] 

这是更为明确的了解你在做什么

2

原因你只得到预期真实,但得到错误是因为starts_with方法返回true或false,而不是实际值。

我不确定这是最好的方法,但您可以自己输出。

users.each {|u| 
    p u.name if !u.name.starts_with?("s") 
    u.name.should be_starts_with("s") 
    } 
+0

我觉得我找到了一个很好的解决方案,我把它作为答案发布,并且会等待看看我的解决方案上有什么红宝石评论 –

+3

这更像是一个关于测试问题的创可贴。如果失败信息不明显,则应该(通常是)测试的写法不正确。 – coreyhaines

0

我在这里找到了一个有趣的延伸,从Rspec的匹配器有关的每个: http://xtargets.com/2011/08/12/rspec-meta-expectations-over-collections

所以我贴的是帮助到我的spec_helper

RSpec::Matchers.define :each do |meta| 
    match do |actual| 
    actual.each_with_index do |i, j| 
    @elem = j 
    i.should meta 
    end 
end 

failure_message_for_should do |actual| 
    "at[#{@elem}] #{meta.failure_message_for_should}" 
end 

,让我写

users.should each satisfy {|u| u.name.should be_starts_with 's'} 

然后错误信息是:

at[1] expected #User to satisfy block

这给了我失败的第一个索引。 除了一些额外的错误消息,我敢肯定我可以输出不匹配的对象的细节,这似乎是一个很好的解决方案。

有什么想法?我不是一个红宝石主义者,刚开始使用Rails。会是不错的,从

1

这里得到更多的投入是我用过几次的情况下是这样的方式:

describe 'user' do 
    before :each do 
    @users = users.search(:name => "s") 
    end 

    @users.each do |u| 
    it "should filter user with name '#{u.name}'" do 
     u.name.should be_starts_with("s") 
    end 
    end 

end 

你会在你没有用户名例子说明。

+0

不会运行搜索每个'它'应该...“'?之前:都可能? –

+0

确定,之前:全部甚至是使用让。我更新了代码 – vanyak

+0

let与示例同时进行评估,而不是以构建时间为例。不同的范围,所以在构建示例时你将无法访问filtered_users。 (除非我正在阅读你缺乏的parens和: – coreyhaines

0

这应该为您提供远更好的失败信息

it "should filter by name" do 
    users = users.search(:name => "s") 
    users.each do |u| 
    u.name.should match /^s/ 
    end 
end 

我同意科里说的“be_starts_with”很粗糙。 RSpec期望旨在作为句子流畅地阅读。他们并不都必须使用“be”。

+0

用一个正则表达式的匹配替换一个字符串的'start_with?'来满足rspec听起来有点Procrustean。 –

+0

巨大的为了便于阅读,改进了“be_starts_with”。 –

+0

'u.name.should start_with?(“s”)'work? –

相关问题