问题
I am trying to learn cucumber, here's an example code from a book:
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
When I run this spec, I get this error:
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
See that it gives undefined method 'messages'
error, yet it is defined in the Output
class.
If I replace output.messages.should
with Output.new.messages.should
, it works fine. What is the problem here?
Edit: Probably output
is a keyword, in new version of rails, when I changed it to outputz
it worked fine. An explanation of this will be accepted as an answer.
回答1:
Apparently, the output matcher has been added to rspec in version 3.0:
The output matcher provides a way to assert that the has emitted content to either
$stdout
or$stderr
.With no arg, passes if the block outputs to_stdout or to_stderr. With a string, passes if the blocks outputs that specific string to_stdout or to_stderr. With a regexp or matcher, passes if the blocks outputs a string to_stdout or to_stderr that matches.
Examples:
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 }
来源:https://stackoverflow.com/questions/26850871/newbie-cant-define-a-method-in-ruby-for-cucumber-test-pass