2013-08-23 98 views
0

我正在通過學​​習ruby教程,我試圖通過測試可打印方法的最後一個示例。我通過直接在我的ruby程序中調用該方法來測試該方法,並且精確地分析出需要的東西。什麼阻止我的代碼正確傳遞?任何幫助是極大的讚賞。rspec測試未通過

這裏的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)> 
' 

回答

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會將它們附加到單個字符串中。

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