rspec测试没有通过

时间:2013-08-23 07:59:43

标签: ruby rspec

我正在学习ruby教程,我正在尝试通过最后一个测试可打印方法的例子。我通过直接在我的ruby程序中调用该方法测试了该方法,并且它确实吐出了所需的内容。什么阻止我的代码正确传递?非常感谢任何帮助。

这是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

这是我迄今为止为可打印功能创建的内容:

class Dictionary
def initialize(opts = {})
    @opts = opts
end

def entries
    @opts
end

def add(opts)
    opts.is_a?(String) ? @opts.merge!(opts => nil) : @opts.merge!(opts)
end

def keywords
    @opts.keys.sort
end

def include?(key)
    @opts.has_key?(key)
end

def find(key)
    @opts.select { |word,defin| word.scan(key).join == key }
end

def printable
    opts_sorted = @opts.sort_by { |word,defin| word}
    opts_sorted.each do |word,defin|
        print "[#{word}] \"#{defin}\"\n"
    end
end
end

这是错误:

  1) Dictionary can produce printable output like so: [keyword] "definition"
     Failure/Error: @d.printable.should == %Q{[apple] "fruit"\n[fish] "aquatic animal
"\n[zebra] "African land animal with stripes"}
       expected: "[apple] \"fruit\"\n[fish] \"aquatic animal\"\n[zebra] \"African lan
d animal with stripes\""
            got: [["apple", "fruit"], ["fish", "aquatic animal"], ["zebra", "African
land animal with stripes"]] (using ==)
       Diff:
       @@ -1,4 +1,4 @@
       -[apple] "fruit"
       -[fish] "aquatic animal"
       -[zebra] "African land animal with stripes"
       +["apple", "fruit"]
       +["fish", "aquatic animal"]
       +["zebra", "African land animal with stripes"]
     # ./11_dictionary/dictionary_spec.rb:81:in `block (2 levels) in <top (required)>
'

2 个答案:

答案 0 :(得分:1)

幸运的是,我刚刚完成了这件事!下面是答案代码,附有解释说明!我希望即使4年后这仍然有用!

class Dictionary                                                  # Create the class
  attr_accessor :entries                                          # Attribute Accessor; this is our setter and getter

  def initialize(entries = {})                                    # Create constructor; if there is no value passed the default value is {}
    @entries = {}                                                 # Declare instance variable with empty hash

    if entries.is_a? Hash                                         # is_a? is a method where it sees if its a class; Hash is the class we compare it to
      entries.each {|key, value| @entries[key] = value}           # if there is a value that's passed we copy the hash to our instance variable
    end                                                           # End conditional 
  end                                                             # End constructor

  def keywords                                                    # Main purpose of this method is to return what's inside our keys
    keywords = []                                                 # Create empty keyword variable
    @entries.each_key {|key| keywords.push(key.to_s)}             # each_key method only takes the keys in our hash and pushes them into the keywords array
    keywords.sort                                                 # We sort the keywords variable 
  end                                                             # End method 

  def add(entry)                                                  # add method adds in an entry either a hash or a string
    if entry.is_a? Hash                                           # If the argument belongs to the class Hash; or if its a hash
      entry.each {|key, value| @entries[key] = value}             # Then we copy the key and values to our instance variable
    elsif entry.is_a? String                                      # If the arguemnt belongs to the class String; or if its a String
      @entries[entry] = nil                                       # We create a key for that string and set the value to nil 
    end                                                           # End conditional 
  end                                                             # End method 

  def include?(entry)                                             # include? method this checks if the argument is in our entries and returns a boolean value
    @entries.has_key?(entry)                                      # has_key? checks the instance variable if it has the key 
  end                                                             # End method 

  def find(entry)                                                 # find method finds if certain letters are in our keys
    @entries.select {|key| /#{entry}/.match(key)}                 # select gets the keys that match a certain keyword in our entries
    # if @entries.has_key?(entry)                                 # First attepmt to solve the test case
    #   @entries.select {|key,value| key == entry}
    # else
    #   puts {}
    # end
  end                                                             # End method 

  def printable                                                   # printable method just prints out our entries like a dictionary
    printable = []                                                # Create an empty array 
    @entries.sort.each do |key,value|                             # Sort and iterate to each key-value pair 
      printable.push("[#{key}] \"#{value}\"")                     # push the key-value pair formatted accordingly to the test case
    end                                                           # End hash iteration

    printable.join("\n")                                          # join with newlines to get desired result
  end                                                             # End method 
end                                                               # End class

答案 1 :(得分:0)

我认为问题是你的printable方法没有返回你希望它返回的内容。

printable的返回值是方法的最后一个语句(opts_sorted.each ...)的值。您正在使用print输出预期的字符串,但这不会更改方法的返回值(这是您正在测试的)。

如果您想要返回正在打印的字符串,请尝试以下操作:

def printable
  opts_sorted = @opts.sort_by { |word, defin| word}
  opts_sorted.map{ |word, defin| "[#{word}] \"#{defin}\"\n" }.join
end

map会将哈希中的键值对转换为按照您希望的方式格式化的字符串数组,然后join会将它们附加到单个字符串中。