You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RSpec实例变量测试失败求助:无法保存用户输入

问题分析与修复

测试代码核心问题:执行顺序颠倒

你当前的测试是先获取实例变量,再调用方法,此时@name还未被赋值,自然是空字符串。正确逻辑应该是先执行get_names完成变量赋值,再获取变量做断言。

原方法的潜在bug

除测试顺序外,get_names方法本身存在几个问题:

  • 使用未初始化的局部变量name,会触发NameError
  • 判断@player1 == ''逻辑错误,新实例的@player1初始值是nil而非空字符串
  • 赋值时误用局部变量name,而非实例变量@name

修复后的测试代码

describe Game do
  subject(:game_names) { described_class.new }

  describe '#get_names' do
    context 'when a user inputs name' do
      it 'saves in name instance variable' do
        # 模拟用户输入'joe'
        allow(game_names).to receive(:gets).and_return('joe')
        # 先执行方法完成赋值
        game_names.get_names
        # 再获取实例变量并断言
        name = game_names.instance_variable_get(:@name)

        expect(name).to eq 'joe'
      end
    end
  end
end

修复后的get_names方法

def get_names
  while Player.players < 2
    # 初始化实例变量,避免未定义错误
    @name ||= ''
    while @name.length <= 2
      puts 'Each player must choose a name'
      print 'Enter a name: '
      @name = gets.chomp
    end

    unless @name == ''
      # 判断@player1是否未初始化(nil),而非是否等于空字符串
      @player1.nil? ? @player1 = Player.new(@name) : @player2 = Player.new(@name)
      @name = ''
      puts 'Name have been saved successfully'
    end
  end
end

额外说明

  1. 如果Player.players初始值为0,需要模拟两次输入才能退出外层循环,否则测试会卡在循环内。可补充模拟第二次输入:
    allow(game_names).to receive(:gets).and_return('joe', 'bob')
    
  2. 建议给Game类的@player1和@player2设置默认值(如nil),避免判断逻辑出错。

内容的提问来源于stack exchange,提问作者Ruiyot Abby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:45:41