I'm new to Ruby and am just learning RSpec. I've written a test for a certain method and keep getting the failing test error:
Failure/Error: if @board[5][@move - 1] == EMPTY_CIRCLE
NoMethodError:
undefined method `-' for nil:NilClass
I know that the code in the Class file does actually work as it should but I just can't seem to get the test to pass.
Here is the Class file code:
class ConnectFour
attr_accessor :player_one, :player_two, :move, :current_player, :board
EMPTY_CIRCLE = "\e[37m\u25cb".freeze
YELLOW_CIRCLE = "\u001b[33m\u25cf".freeze
RED_CIRCLE = "\u001b[31m\u25cf".freeze
def initialize
@board = Array.new(6){Array.new(7,EMPTY_CIRCLE)}
@player_one = nil
@player_two = nil
end
def play_round
print_board
prompt_player
@move = prompt_move
place_marker
end
def prompt_move
loop do
@move = gets.chomp.to_i
return @move if valid_move?(@move)
puts "Invalid input. Enter a column number between 1 and 7"
end
end
def valid_move?(move)
@move.is_a?(Integer) && @move.between?(1, 7)
end
def place_marker
if @board[5][@move - 1] == EMPTY_CIRCLE
@board[5][@move - 1] = @current_player.marker
end
end
end
And here is the RSpec test code:
describe ConnectFour do
subject(:game) { described_class.new }
let(:player){ double(Player) }
describe '#place_marker' do
context 'when column is empty' do
before do
move = 4
allow(game).to receive(:move).and_return(4)
end
it 'places marker on bottom row' do
game.place_marker
expect{game.place_marker}.to change{@board[5][3]}
end
end
end
end
I've tried multiple things but just can't get the test method to recognize the value for @move i'm trying to send it. Any suggestions would be greatly appreciated!.
CodePudding user response:
@move
is nil. You're stubbing out a move
method (that doesn't seem to exist) to return 4
, but this has nothing to do with the @move
variable.
Either make sure @move
is set, or modify your code so that it actually has a move
method and that all direct reads to @move
instead use this method, so your stub can work.
CodePudding user response:
Here's how you can stub @move attr_accessor to return a value:
allow(game).to receive(:move=).with(move: 2)