我正在使用The RSpec Book学习 Rspec + Cucumber 。我才刚刚开始,正在开发 Codebreaker 游戏。
其中,有一个功能“Codebreaker 开始游戏”,它代表用户在 shell 中键入命令并得到两个响应:“欢迎使用 Codebreaker!” 和“输入猜测:”。这是该功能的外观:
Feature: code-breaker starts game
As a code-breaker
I want to start a game
So that I can break the code
Scenario: start game
Given I am not yet playing
When I start a new game
Then I should see "Welcome to Codebreaker!"
And I should see "Enter a guess:"
由于cucumber
脚本使用了输出,因此本书正在创建一个模拟对象output
,该对象期望接收puts
带有参数Welcome to Codebreaker!
的消息。Enter a guess:
这是它在步骤定义中的外观:
#the mock object
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
好的,到目前为止没有问题。
做这个练习,我记得之前看过 rspeck doubles 框架可以在 cucumber 内部使用,所以我想我可以稍微清理一下。
首先,我将 rspeck doubles 框架包含在support/env.rb
:
require 'cucumber/rspec/doubles'
然后我更改了步骤定义:
Given /^I am not yet playing$/ do
end
When /^I start a new game$/ do
@output = double('output').as_null_object #the mock object
game = Codebreaker::Game.new(@output)
game.start
end
Then /^I should see "([^"]*)"$/ do |message|
@output.should_receive(:puts).with(message)
end
奇怪的想法是,现在,当我用 cucumber 执行功能时,在总结中我得到了所有 4 个步骤,但不是整个场景。这怎么可能?这是怎么回事?这是我从命令行获得的输出:
Feature: code-breaker starts game
As a code-breaker
I want to start a game
So that I can break the code
Scenario: start game # features/codebreaker_starts_game.feature:6
Given I am not yet playing # features/step_definitions/codebreaker_steps.rb:1
When I start a new game # features/step_definitions/codebreaker_steps.rb:4
Then I should see "Welcome to Codebreaker!" # features/step_definitions/codebreaker_steps.rb:10
And I should see "Enter a guess:" # features/step_definitions/codebreaker_steps.rb:10
(Double "output").puts("Welcome to Codebreaker!")
expected: 1 time
received: 0 times (RSpec::Mocks::MockExpectationError)
/home/a_user/www/codebreaker/features/step_definitions/codebreaker_steps.rb:11:in `block in <top (required)>'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/error_generator.rb:80:in `__raise'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/error_generator.rb:39:in `raise_expectation_error'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/message_expectation.rb:251:in `generate_error'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/message_expectation.rb:207:in `verify_messages_received'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/method_double.rb:117:in `block in verify'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/method_double.rb:117:in `each'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/method_double.rb:117:in `verify'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/proxy.rb:88:in `block in verify'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/proxy.rb:88:in `each'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/proxy.rb:88:in `verify'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/methods.rb:116:in `rspec_verify'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/space.rb:11:in `block in verify_all'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/space.rb:10:in `each'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks/space.rb:10:in `verify_all'
/var/lib/gems/1.9.1/gems/rspec-mocks-2.10.1/lib/rspec/mocks.rb:19:in `verify'
/var/lib/gems/1.9.1/gems/cucumber-1.1.9/lib/cucumber/rspec/doubles.rb:12:in `After'
Failing Scenarios:
cucumber features/codebreaker_starts_game.feature:6 # Scenario: start game
1 scenario (1 failed)
4 steps (4 passed)
0m0.009s