2012-05-29 70 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。也許這就是爲什麼黃瓜不鼓勵嘲笑的原因之一,因爲這個事件必須被宣佈與期望分離。相反,它應該在書中完成(因爲它檢查的是狀態而不是行爲)。請,如果我在這個推理中錯了,告訴我一些事情,我是一個所有這些東西的新手:) –