如何修复国际象棋游戏RSpec测试中的‘received unexpected message’错误?
修复RSpec InstanceDouble未预期消息错误
问题核心原因
你碰到的错误有两个关键诱因:
instance_double默认处于严格模式:所有被调用的方法必须提前用allow声明允许接收,包括setter方法(比如square_collection=)。你当前只允许了读方法square_collection,没处理对应的写方法。allow(board).to receive(:create_board)未指定返回值,默认返回nil,这会导致square_collection被赋值为nil(如果业务逻辑要求非nil值,这也需要调整)。
具体修复步骤
1. 允许Board实例接收square_collection=消息
在测试的before块中,添加一行允许setter方法的代码:
allow(board).to receive(:square_collection=)
2. (可选但推荐)给create_board指定合理返回值
如果业务逻辑中create_board应该返回非nil的集合(比如数组或自定义对象),可以给它指定返回值,避免赋值nil:
# 示例:模拟返回空数组,可根据实际业务替换为符合要求的对象 allow(board).to receive(:create_board).and_return([])
3. 补全Square的status=方法允许
注意到被测代码里有board.get_square(piece.position).status = piece,这意味着需要允许square接收status=消息——你原来只允许了status读方法,必须补上setter的允许,否则会触发新的未预期消息错误:
allow(square).to receive(:status=)
修改后的完整before块
before do allow(board).to receive(:square_collection) allow(board).to receive(:square_collection=) # 新增:允许square_collection的setter方法 allow(board).to receive(:create_board).and_return([]) # 新增:指定create_board的返回值 allow(white).to receive(:pieces).and_return([pawn, pawn, pawn]) allow(black).to receive(:pieces).and_return([pawn, pawn, pawn]) allow(pawn).to receive(:position) allow(board).to receive(:get_square).and_return(square) allow(square).to receive(:status) allow(square).to receive(:status=) # 新增:允许status的setter方法 game.board = board game.white = white game.black = black end
额外说明
instance_double的严格模式是为了确保测试只调用真实类中存在的方法,避免测试中出现拼写错误或调用不存在的方法。所有在被测代码中调用的实例方法(包括getter、setter)都必须提前用allow或expect声明。
内容的提问来源于stack exchange,提问作者Thảo Nguyễn
相关产品推荐
相关产品推荐

