如何用Ruby Minitest测试调用自身的递归游戏循环方法
问题根因
你的测试代码在执行到@game.stub :getPlayerSet, raise(StandardError)这一行时就直接抛出了错误,并未进入后续的assert_raises捕获块。问题出在stub的第二个参数是直接求值的表达式,raise(StandardError)会在给方法打桩的瞬间就执行,而不是等到getPlayerSet被实际调用时才触发。
同时你当前模拟的输入是空字符串,无法命中"a"对应的case分支,就算抛错逻辑生效也无法验证目标分支的逻辑。
修复方案
将抛错逻辑封装为lambda(只有被调用时才会执行内部逻辑),同时调整模拟输入为"a"命中目标分支,修复后的测试代码如下:
def test_playRound_a_input_triggers_getPlayerSet # 用lambda封装抛错逻辑,仅方法调用时才执行 stub_error = -> { raise StandardError } @game.stub :getPlayerSet, stub_error do assert_raises(StandardError) do # 模拟输入改为"a"命中对应case分支 simulate_stdin("a") { @game.playRound } end end end
更优的测试实现
不需要通过抛错绕开递归,直接桩住后续的playRound调用,并用mock验证目标方法是否被调用,测试逻辑更清晰:
def test_playRound_a_input_triggers_getPlayerSet # 创建mock验证getPlayerSet被调用 get_player_set_mock = Minitest::Mock.new get_player_set_mock.expect :call, nil @game.stub :getPlayerSet, get_player_set_mock do # 桩住playRound避免后续递归执行 @game.stub :playRound, nil do simulate_stdin("a") { @game.playRound } end end # 验证方法确实被调用 get_player_set_mock.verify end
内容的提问来源于stack exchange,提问作者DesPhantomes
相关产品推荐
相关产品推荐

