首页 > 解决方案 > 无论输入如何,Rspec 测试始终通过

问题描述

我正在尝试在我的连接四游戏中测试以下方法。当玩家试图将一个棋子放在一个完整的列中时,:puts屏幕上会出现错误消息。

我遇到的问题是,无论我输入的是全列还是空列的板,测试都通过了。我也看到了这个错误消息:WARNING: An expectation of `:puts` was set on `nil`.我解释为boardor@player值没有被正确地传递到最终expect()赋值中。

这个测试我哪里出错了?谢谢!

正在测试的方法:

def valid_vertical_move
  until @game_board.board[5][@player - 1] == '.'
    puts 'Please place piece in valid spot'
    player_selection
  end
end

这是我尝试过的众多测试之一:

describe Game do

  describe '#valid_vertical_move' do
    subject(:valid_move) { described_class.new(new_board) }
    let(:new_board) {double('new_board', :board => [['x', 'x', 'x', 'x', '.', '.', '.'], 
      ['y', '.', '.', '.', '.', '.', '.'], ['y', '.', '.', '.', '.', '.', '.'], 
      ['y', '.', '.', '.', '.', '.', '.'], ['x', '.', '.', '.', '.', '.', '.'], 
      ['x', '.', '.', '.', '.', '.', '.']])}

    context 'when the column is full' do

      before do
        allow(valid_move).to receive(:player_selection)
      end

      it 'an error message is :puts' do
         error_message = 'Please place piece in valid spot'
         test = valid_move.valid_vertical_move
         expect(test).to receive(:puts).with(error_message)

      end
    end
  end
end

游戏类:

class Game

  attr_reader :player

  def initialize(game_board = Board.new)
    @game_board = game_board
    @player_turn = 1
    @player = 0
  end

  def player_selection
    loop do
      puts "Choose a column, Player #{@player_turn}:"
      @user_input = gets.chomp

      if @user_input.match?(/\b[1-7]\b/)
        return @player = @user_input.to_i
      else
        puts 'Error: Add number between 1-7'
      end
    end
  end

  def valid_vertical_move
    until @game_board.board[5][@player - 1] == '.'
      puts 'Please place piece in valid spot'
      player_selection
    end
  end
end

板级:

class Board
  attr_reader :board

  def initialize(board = Array.new(6) { Array.new(['.', '.', '.', '.', '.', '.', '.']) })
    @board = board
  end

  def display_board(board = @board)
    puts "| #{board[5][0]} | #{board[5][1]} | #{board[5][2]} | #{board[5][3]} | #{board[5][4]} | #{board[5][5]} | #{board[5][6]} |"
    puts "| #{board[4][0]} | #{board[4][1]} | #{board[4][2]} | #{board[4][3]} | #{board[4][4]} | #{board[4][5]} | #{board[4][6]} |"
    puts "| #{board[3][0]} | #{board[3][1]} | #{board[3][2]} | #{board[3][3]} | #{board[3][4]} | #{board[3][5]} | #{board[3][6]} |"
    puts "| #{board[2][0]} | #{board[2][1]} | #{board[2][2]} | #{board[2][3]} | #{board[2][4]} | #{board[2][5]} | #{board[2][6]} |"
    puts "| #{board[1][0]} | #{board[1][1]} | #{board[1][2]} | #{board[1][3]} | #{board[1][4]} | #{board[1][5]} | #{board[1][6]} |"
    puts "| #{board[0][0]} | #{board[0][1]} | #{board[0][2]} | #{board[0][3]} | #{board[0][4]} | #{board[0][5]} | #{board[0][6]} |"
    puts "  1 | 2 | 3 | 4 | 5 | 6 | 7  "
  end
end

标签: ruby-on-railsrubyrspecautomated-teststdd

解决方案


基本上你期望一个 niltest = valid_move.valid_vertical_move接收一个方法调用,这不是你在这里似乎想要做的。您可能想在此处提出或记录一些错误,然后测试 Rails.logger 以接收一些电话或其他东西。


推荐阅读