LocalJumpError:没有给出块

时间:2015-04-09 22:59:43

标签: ruby rspec

运行rspec文件时出现错误:

Failures:                                                                                                                                  

  1) Book title should capitalize the first letter                                                                                         
     Failure/Error: @book.title("inferno")                                                                                                 
     LocalJumpError:                                                                                                                       
       no block given (yield)                                                                                                              
     # ./08_book_titles.rb:7:in `title'  

这里是book_title.rb

class :: Book

  attr_accessor :some_title

def title(some_title)
little_words = %w(of and for the over under an a but or nor yet so at around by after along from on to with without)
  some_title = yield
  some_title.split.each_with_index.map{|x, index| little_words.include?(x) && index > 0 ? x : x.capitalize }.join(" ")
end #def

end

这里是rspec文件(或者至少是第一个规范):

require_relative '08_book_titles'

describe Book do

  before do
    @book = Book.new
  end

  describe 'title' do
    it 'should capitalize the first letter' do
      @book.title("inferno")
      @book.title.should == "Inferno"
    end
end

我已经在方法中包含了yield,并且规范中有一个块...所以我不明白它为什么不调用那个块。我已经尝试了我能想到的一切,直接在地图上调用它(而不是使用它被赋予的变量)来单独调用它,然后在地图上使用它,尝试将其作为标题的参数传递给它在方法中...到你现在看到的。我还阅读了大量的帖子。我没看到什么?

我看到未来的练习也将运行自定义类的规范,所以我也喜欢在使用rspec测试自定义类时我需要知道或注意的一些提示(或链接)。谢谢!

已更新

所以我把book_title.rb改成了这样:

  class :: Book

  def title
little_words = %w(of and for the over under an a but or nor yet so at around by after along from on to with without)
    self.split.each_with_index.map{|x, index| little_words.include?(x) && index > 0 ? x : x.capitalize }.join(" ")
end #def

end

因为我可能不正确地编辑了规范 - 我将它们还原为:

require '08_book_titles'

describe Book do

  before do
    @book = Book.new
  end

  describe 'title' do
    it 'should capitalize the first letter' do
      @book.title = "inferno"
      @book.title.should == "Inferno"
    end
end

我现在得到的错误是:

Failure/Error: @book.title = "inferno"                                                                                                
     NoMethodError:                                                                                                                        
       undefined method `title=' for #<Book:0x007f292a06c6b0>                                                                              
     # ./08_book_titles_spec.rb:26:in `block (3 levels) in <top (required)>' 

2 个答案:

答案 0 :(得分:2)

你误用yield而不是,规范中没有阻止。如果有的话,规格看起来像......

  @book.title("inferno") do
    "inferno"
  end

看到我添加的块?但是你不需要块,你不应该使用yield

您似乎认为需要yield来访问论证......您不需要。您的title方法应该直接使用传递的参数...

def title(new_title)
little_words = %w(of and for the over under an a but or nor yet so at around by after along from on to with without)
  @some_title = new_title.split.each_with_index.map{|x, index| little_words.include?(x) && index > 0 ? x : x.capitalize }.join(" ")
end #def

最后,您的测试实际上是调用title方法两次,此时您应该只调用一次并使用attr_accessor方法来测试结果。

it 'should capitalize the first letter' do
  @book.title("inferno")
  @book.some_title.should == "Inferno"
end

答案 1 :(得分:2)

关于您的编辑,您无法执行self.split,因为self是Book对象,而不是字符串。

您可以修改title方法,使其成为setter方法...将其设为title=而不是title

  def title=(new_title)
little_words = %w(of and for the over under an a but or nor yet so at around by after along from on to with without)
    @title = new_title.split.each_with_index.map{|x, index| little_words.include?(x) && index > 0 ? x : x.capitalize }.join(" ")
end #def

它为您提供了测试所说的“title =”方法。你可以创建一个getter方法......

def title
  @title
end

现在你的测试(正如你所写的那样)应该可以正常工作。