0

RSpecBookでRspec+Cucumberを学んでいます。Codebreakerゲームを開発している間、私はまだ始まったばかりです。

その中には、ユーザーがシェルにコマンドを入力し、「Codebreakerへようこそ!」という2つの応答を受け取るだけの「Codebreakerstartsgame」機能があります。および「推測を入力してください:」。機能は次のようになります。

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を受信することを期待しているモックオブジェクトを作成しています。ステップ定義での表示は次のとおりです。putsWelcome 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フレームワークを使用できるようになる前に読んだことを思い出したので、少しきれいにできると思いました。

まず、rspeckdoublesフレームワークを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

奇妙な考えは、キュウリを使って機能を実行すると、要約すると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
4

1 に答える 1

1

のような期待値を設定するshould_receiveと、将来のある時点で指定されたメソッドが呼び出されるように指定します。以前に発生したことはすべて無視されます(そうでない場合は、過去形のhave_receivedなど)。

コードでは、ステップで期待値を設定していますThenが、メソッドはWhenステップで(つまり前に)呼び出されるため、その時点では期待値は設定されていません。doubleは、任意のメソッドを呼び出すことができるように設定されているため、エラーは発生しませんが、最後に仕様がすべての期待が満たされているかどうかをチェックすると、noと表示され、例外が発生します。

于 2012-05-29T08:54:28.667 に答える