Jest Mock prompt-sync模块失败:Player类promptPlayer测试异常排查
问题分析与解决方案
核心问题
测试失败并进入无限循环的根源有两个:
- validOption函数逻辑错误:prompt返回的是字符串类型输入,但该函数首先判断
typeof(row) !== "number",直接将合法的字符串输入判定为无效,触发promptPlayer递归调用。 - mock返回值耗尽:测试中仅设置了两次mock返回值,递归调用后prompt函数返回undefined,进一步导致row/col变量为undefined,加剧循环。
修复步骤
1. 修正validOption的逻辑
调整函数逻辑,先将输入转换为数字再验证有效性,而非先判断类型:
validOption(emptySlots, rowInput, colInput) { // 先将输入转为数字 const row = parseInt(rowInput); const col = parseInt(colInput); // 验证是否为有效数字且在0-2范围内 if (isNaN(row) || isNaN(col) || row < 0 || row >= 3 || col < 0 || col >= 3) { return false; } // 验证目标插槽是否为空 return emptySlots[row][col] === "."; }
2. 确保测试mock逻辑正常
你的测试mock写法本身无问题,修复validOption后,递归不会触发,mock的两次返回值刚好满足一次promptPlayer调用的两次prompt请求,测试即可正常通过。如果需要测试无效输入的递归场景,需为mock添加更多返回值:
it("promptPlayer returns { row, col, mark }", () => { const mockPrompt = require("prompt-sync")(); // 模拟正确输入:先返回行0,再返回列2 mockPrompt.mockReturnValueOnce("0").mockReturnValueOnce("2"); const result = player.promptPlayer(emptySlots); expect(result).toEqual({ row: 0, col: 2, mark: "X" }); // 验证prompt被调用两次 expect(mockPrompt).toHaveBeenCalledTimes(2); })
测试验证
修复后,validOption会正确处理字符串输入,mock的返回值能被正常接收,promptPlayer不会触发无限递归,测试即可顺利通过。
内容的提问来源于stack exchange,提问作者Mohamed
相关产品推荐
相关产品推荐

