2012-05-29 71 views
0

我正在学习Rspec +黄瓜The RSpec Book。我只是在开始时,开发一个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这是期待着与Welcome to Codebreaker!Enter a guess:参数收到puts消息。这里是它在步骤定义中的外观:

#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双打框架可以用在黄瓜里面,所以我想我可以把它清理一下。

首先,我已经包含在support/env.rb rspeck双打框架:

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 

奇怪认为,现在,当我执行的功能与黄瓜,在总结我得到所有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 

回答

1

当您设定一个期望像should_receive,你指定在未来某一时刻的指定方法应该叫 - 任何先前发生被忽略了(否则它应该是已经存在的或类似过去式的东西)。

在您的代码中,您将在Then步骤中设置期望值,但该方法会在您的When步骤(即之前)中调用,因此此时没有设置期望值。你的双重设置允许任何方法被调用,所以你没有任何错误,但是当规范检查到底是否所有的期望已经满足时,它会说不,并提出异常

+0

好吧!我明白了,非常感谢@FrederickCheung。也许这就是为什么黄瓜不鼓励嘲笑的原因之一,因为这个事件必须被宣布与期望分离。相反,它应该在书中完成(因为它检查的是状态而不是行为)。请,如果我在这个推理中错了,告诉我一些事情,我是一个所有这些东西的新手:) –