新手无法在红宝石中定义黄瓜测试通过的方法

时间:2014-11-10 18:55:21

标签: ruby-on-rails ruby rspec tdd cucumber

我正在尝试学习黄瓜,这是一本书中的示例代码:

class Output
  def messages
    @messages ||= []
  end

  def puts(message)
    messages << message
  end
end

def output
  @output ||= Output.new
end

Given /^I am not yet playing$/ do
end

When /^I start a new game$/ do
  game = Codebreaker::Game.new(output)
  game.start
end

Then /^I should see "([^"]*)"$/ do |message|
  output.messages.should include(message)
end

当我运行此规范时,我收到此错误:

  Scenario: start game                          # features/codebreaker_starts_game.feature:7
    Given I am not yet playing                  # features/step_definitions/codebreaker_steps.rb:15
    When I start a new game                     # features/step_definitions/codebreaker_steps.rb:18
    Then I should see "Welcome to Codebreaker!" # features/step_definitions/codebreaker_steps.rb:23
      undefined method `messages' for #<RSpec::Matchers::BuiltIn::Output:0xa86a7a4> (NoMethodError)
      ./features/step_definitions/codebreaker_steps.rb:24:in `/^I should see "([^"]*)"$/'
      features/codebreaker_starts_game.feature:10:in `Then I should see "Welcome to Codebreaker!"'
    And I should see "Enter guess:"             # features/step_definitions/codebreaker_steps.rb:23

看到它出现undefined method 'messages'错误,但它已在Output类中定义。

如果我将output.messages.should替换为Output.new.messages.should,则可以正常使用。这有什么问题?

修改:可能output是一个关键字,在新版本的rails中,当我将其更改为outputz时,它运行正常。对此的解释将被接受为答案。

1 个答案:

答案 0 :(得分:3)

显然,版本3.0中已将output matcher添加到rspec:

  

输出匹配器提供了断言已发出的方法   内容为$stdout$stderr

     

如果没有arg,则在块输出to_stdout或to_stderr时传递。同   如果块输出特定字符串to_stdout,则传递一个字符串   或to_stderr。使用正则表达式或匹配器,如果块输出a则通过   匹配的字符串to_stdout或to_stderr。

示例:

RSpec.describe "output.to_stdout matcher" do
  specify { expect { print('foo') }.to output.to_stdout }
  specify { expect { print('foo') }.to output('foo').to_stdout }
  specify { expect { print('foo') }.to output(/foo/).to_stdout }
  specify { expect { }.to_not output.to_stdout }
  specify { expect { print('foo') }.to_not output('bar').to_stdout }
  specify { expect { print('foo') }.to_not output(/bar/).to_stdout }