Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
868 views
in Technique[技术] by (71.8m points)

ruby - Rspec Instance Double Received Unexpected Message

I'm writing rspec tests for my #check? method within my chess game but hitting an error with the start_coordinates variable stored in my Board class, which in rspec is an instance double.

Unsure how to allow my #check? method to change start_coordinates in rspec when it runs.

  def check?(king_coordinates)
    check = nil
    @chess.board.each do |array|
      array.each do |square|
        next if square == '' || square.which_player != whos_turn

        if square.which_player == whos_turn
          row = @chess.board.detect{ |aa| aa.include?(square) }
          @chess.start_coordinates = [row.index(square) + 1, 8 - @chess.board.index(row)]
          check = square.valid_move?(@chess, square.which_player) ? true : false
        else
          false
        end
      end
    end
    check
  end

My rspec looks like this:

  describe '#check?' do
    subject(:game_check) { described_class.new(player_one, player_two, board_class)}

    let(:board_class) { instance_double(Board, board: [
      ['', '', rook, '', '', '', king, ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', bishop, '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', '']
    ], start_coordinates: nil, finish_coordinates: nil) }
  
    before do
      allow(game_check).to receive(:whos_turn).and_return(player_one)
      ## allow(board_class).to receive(:start_coordinates).and_return([3, 8]) ## Tried this 
    end

    it 'returns true' do
      expect(game_check.check?([7, 8])).to eq(true)
    end
  end

My error message is:

  #<InstanceDouble(Board) (anonymous)> received unexpected message :start_coordinates= with ([3, 8])

I have tried shown in the code above:

  allow(board_class).to receive(:start_coordinates).and_return([3, 8])

Update to show Board class:

lass Board
  attr_reader :board, :start_coordinates, :start_square, :finish_coordinates, :finish_square

  def initialize(player1, player2)
    @player1 = player1
    @player2 = player2

    @start_square = nil
    @finish_square = nil
    @start_coordinates = []
    @finish_coordinates = []

    @board = [
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', ''],
      ['', '', '', '', '', '', '', '']
    ]
  end
question from:https://stackoverflow.com/questions/65680190/rspec-instance-double-received-unexpected-message

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are calling the "setter" method start_coordinates= but you are only "allowing" the "getter" method start_coordinates.

Instead try changing

 allow(board_class).to receive(:start_coordinates).and_return([3, 8])

To

allow(board_class).to receive(:start_coordinates=)

That being said a setter (method ending in =) will always return the argument passed in so and_return is not useful here but you could use with() if you want to be explicit about the arguments :start_coordinates= are expected to receive

Example:

def hello=(n)
'Hi'
end 

hello= 12
#=> 12

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...