The private method "puts"? Can't pass cucumber test in RSpec Book Codebreaker example

I am following in RSpec Book and I am unable to pass the cucumber test to pass a specific location. I even tried to run the cucumber in the source code from the book and it still won't work. I'm not sure if it's a fact that I am using a newer version of cucumber, but there must be a way to do it!

When I get to the point where the program should start a new game, I'm told that the undefined method "puts". Why is it undefined, and how else am I supposed to grab what the program puts

exited in Cucumber? Running a test in RSpec to make sure the game is posting a message is working fine, not sure how to do it in cucumbers.

(cucumber version 1.3.17, Ruby version 2.1.2)

Basically, I have the following possibilities:

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 guess:"

      

and these step definitions:

    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

      

and this ruby ​​code:

    module Codebreaker

        class Game

            def initialize(output)
                @output = output
            end

            def start
                @output.puts 'Welcome to Codebreaker!'
            end
        end
    end

      

and I am getting this error:

When I start a new game                     # features/step_definitions/codebreaker_steps.rb:16
  private method `puts' called for #<RSpec::Matchers::BuiltIn::Output:0x007fa4ea200ad0> (NoMethodError)

  ./lib/codebreaker/game.rb:10:in `start'
  ./features/step_definitions/codebreaker_steps.rb:18:in `/^I start a new game$/'
  features/codebreaker_starts_game.feature:7:in `When I start a new game'

      

How do I fix this so that it runs in a cucumber?

+2


source to share


3 answers


There are many things that have changed since this RSpec book was published, but I got it by replacing your file code_break_steps.rb

with this:

Given /^I am not yet playing$/ do
end

When /^I start a new game$/ do
  @messenger = StringIO.new
  game = Codebreaker::Game.new(@messenger)
  game.start
end

Then /^I should see "([^"]*)"$/ do |message|
  expect(@messenger.string.split("\n")).to include(message)
end

      

RSpec 3 has a class that you are trying to overwrite with a name Output

and this is causing too much confusion. I just simplified it so you are still talking to each other along with stdout

.



You can use the same syntax should

on the last line, but it will soon be deprecated, so it's better to get used to the syntax expect

I was using. For now, if you're more confusing, you can still use:

@messenger.string.split("\n").should include(message)

+6


source


I am following this book right now and tried Anthony's technique. But I got into trouble again a little later in the book (most likely because I'm kind of new to Rails and couldn't translate Anthony's technique to another case ^^). But anyway, I found an easier way to not interfere with the RSpec Output class and still not reject the flow of lessons too much:

  • rename the class Output

    to something else, sayOOutput

  • and change all variables Output

    to o_output

    .


Et voilà; -)

+1


source


I was only able to accomplish this specific example with two changes to the same "codebreaker_steps.rb" file, so you can still follow the book's tutorial. You don't need to touch the class name, only the output () method following it.

RSpec 3 contains an output () method that causes conflicts when trying to define another output () method. So, knowing this, take the instructions for the book:

def output
 @output ||= Output.new
end

      

and rename it to:

def see_output #new
 @output ||= Output.new
end

      

(or name something that makes sense for the project)

Then go to the definition of the When () method:

When /^I start a new game$/ do
 game = Codebreaker::Game.new(output)
 game.start
end

      

and update the second line:

When ("I start a new game") do
 game = Codebreaker::Game.new(see_output) #new
 game.start
end

      

0


source







All Articles