Cucumber test double:场景失败但其步骤通过 [英] Cucumber test double: scenario failing but its steps passing
问题描述
我正在通过 The RSpec Book 学习 Rspec + Cucumber.我才刚刚开始,正在开发 Codebreaker 游戏.
I'm learning Rspec + Cucumber with The RSpec Book. I'm just at the beginning, while developing a Codebreaker game.
其中有一个功能Codebreaker 开始游戏",它代表用户在 shell 中键入命令并得到两个响应:欢迎使用 Codebreaker!"和输入猜测:".这是该功能的外观:
In it, there is a feature "Codebreaker starts game" that represents simply a user typing a command in the shell and getting two responses: "Welcome to Codebreaker!" and "Enter a guess:". Here it is how the feature looks like:
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:
参数.这是它在步骤定义中的样子:
As the output is used by the cucumber
script, the book is creating a mock object output
which is expecting to receive the puts
message with Welcome to Codebreaker!
and Enter a guess:
argument. Here it is how it looks in the step definitions:
#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
好的,到现在都没问题.
Ok, up till now no problem.
做这个练习,我记得之前看过rspeck doubles框架可以用在cucumber里面,所以我想我可以稍微清理一下.
Doing this exercise, I remembered to had read before that rspeck doubles framework could be used inside cucumber, so I thought I could clean it a little bit.
首先,我在 support/env.rb
中包含了 rspeck doubles 框架:
First, I have included rspeck doubles framework in support/env.rb
:
require 'cucumber/rspec/doubles'
然后我更改了步骤定义:
And then I have changed the step definitions:
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
奇怪的想法是,现在,当我用黄瓜执行功能时,在总结中我得到了所有 4 个步骤,但不是整个场景.这怎么可能?这是怎么回事?这是我从命令行得到的输出:
The strange think is that now, when I execute the feature with cucumber, in the summary I get all 4 steps passing but not the whole scenario. How is it possible? What is it happening? Here it is the output I get from the command line:
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
推荐答案
当你设置像 should_receive
这样的期望时,你指定在未来的某个时间点应该调用指定的方法 -之前发生的任何事情都将被忽略(否则应该是 have_received 或过去时的类似内容).
When you set an expectation like should_receive
, you're specifying that a some point in the future the specified method should be called - anything that has happened previously is ignored (or else it would be should have_received or something like that in the past tense).
在您的代码中,您在 Then
步骤中设置了期望,但该方法在您的 When
步骤(即之前)中被调用,所以此时没有期望已设置.您的双重设置允许调用任何方法,因此您不会收到任何错误,但是当规范检查最后是否满足所有期望时,它会拒绝并引发异常
In your code you're setting up the expectation in your Then
step but the method gets called in your When
step (i.e. before), so at that point no expectation has been setup. Your double is setup to allow any method to be called, so you get no errors, but when spec checks at the end whether all expectations have been satisfied it will say no and raise an exception
这篇关于Cucumber test double:场景失败但其步骤通过的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!