我正在使用TestFirst.org的Ruby教程。我目前正在上“词典”课。我被困在关键字示例上。这是Ruby文档以及RSpec文件。
我感到困惑的原因是我不确定这个例子是否正确。如果您遵循RSpec文件,“可以检查给定关键字是否存在”之前的示例使用add方法将“fish”添加到字典中。那么,在给我一个错误的例子中,包含?方法(我需要实现)应该返回false。
它应该返回false吗?我们不是在上面的例子中添加“鱼”吗?或者我错过了什么?
这是我的Ruby程序:
class Dictionary
def initialize
@entries = {}
end
def entries
@entries
end
def keywords
@entries.keys
end
def add(pairings)
if pairings.is_a?(String)
@entries[pairings] = nil
else
pairings.each do |word, definition|
@entries[word] = definition
end
end
end
def include?(keyword)
@entries.keys.include?(keyword)
end
end
以下是RSpec文件: # # 话题 # #*哈希 #*数组 #*实例变量 # * 常用表达 #
require 'dictionary'
describe Dictionary do
before do
@d = Dictionary.new
end
it 'is empty when created' do
@d.entries.should == {}
end
it 'can add whole entries with keyword and definition' do
@d.add('fish' => 'aquatic animal')
@d.entries.should == {'fish' => 'aquatic animal'}
@d.keywords.should == ['fish']
end
it 'add keywords (without definition)' do
@d.add('fish')
@d.entries.should == {'fish' => nil}
@d.keywords.should == ['fish']
end
it 'can check whether a given keyword exists' do
@d.include?('fish').should be_false
end
it "doesn't cheat when checking whether a given keyword exists" do
@d.include?('fish').should be_false # if the method is empty, this test passes with nil returned
@d.add('fish')
@d.include?('fish').should be_true # confirms that it actually checks
@d.include?('bird').should be_false # confirms not always returning true after add
end
it "doesn't include a prefix that wasn't added as a word in and of itself" do
@d.add('fish')
@d.include?('fi').should be_false
end
it "doesn't find a word in empty dictionary" do
@d.find('fi').should be_empty # {}
end
it 'finds nothing if the prefix matches nothing' do
@d.add('fiend')
@d.add('great')
@d.find('nothing').should be_empty
end
it "finds an entry" do
@d.add('fish' => 'aquatic animal')
@d.find('fish').should == {'fish' => 'aquatic animal'}
end
it 'finds multiple matches from a prefix and returns the entire entry (keyword + definition)' do
@d.add('fish' => 'aquatic animal')
@d.add('fiend' => 'wicked person')
@d.add('great' => 'remarkable')
@d.find('fi').should == {'fish' => 'aquatic animal', 'fiend' => 'wicked person'}
end
it 'lists keywords alphabetically' do
@d.add('zebra' => 'African land animal with stripes')
@d.add('fish' => 'aquatic animal')
@d.add('apple' => 'fruit')
@d.keywords.should == %w(apple fish zebra)
end
it 'can produce printable output like so: [keyword] "definition"' do
@d.add('zebra' => 'African land animal with stripes')
@d.add('fish' => 'aquatic animal')
@d.add('apple' => 'fruit')
@d.printable.should == %Q{[apple] "fruit"\n[fish] "aquatic animal"\n[zebra] "African land animal with stripes"}
end
end
答案 0 :(得分:2)
测试是正确的。您遗失的是before
的工作原理。
在RSpec中,before
没有参数的挂钩(或参数:each
)指定在每次测试运行之前要采取的步骤,而不是(如人们所想的那样)在整个测试之前运行的步骤一套测试。
换句话说,before
挂钩在第一次测试之前运行,然后在第二次测试之前运行,然后在第三次测试之前运行,依此类推。
执行顺序如下:
before
强> test1
before
强> test2
before
test3
在您的情况下,虽然在it 'add keywords (without definition)' do
中将'fish'
添加到@d
是正确的,但这不会影响下一个测试,因为before
挂钩之间运行其中两个,并用一个新的空@d
对象替换Dictionary
。因此,在测试#include?
时,您要检查空Dictionary
是否包含'fish'
,而不是before
。
相反,如果您想在执行任何测试之前执行一次步骤,则应将before(:all) do
@d = Dictionary.new
end
块替换为:
Dictionary
在那种情况下,你是对的;测试将使用与之前所有测试相同的true
,因此应该期望{{1}}。