123 lines
5.1 KiB
Python
123 lines
5.1 KiB
Python
import unittest
|
|
from unittest.mock import patch, MagicMock, call
|
|
|
|
from heurams.kernel.puzzles.mcq import MCQPuzzle
|
|
|
|
|
|
class TestMCQPuzzle(unittest.TestCase):
|
|
"""测试 MCQPuzzle 类"""
|
|
|
|
def test_init(self):
|
|
"""测试初始化"""
|
|
mapping = {"q1": "a1", "q2": "a2"}
|
|
jammer = ["j1", "j2", "j3"]
|
|
puzzle = MCQPuzzle(mapping, jammer, max_riddles_num=3, prefix="选择")
|
|
self.assertEqual(puzzle.prefix, "选择")
|
|
self.assertEqual(puzzle.mapping, mapping)
|
|
self.assertEqual(puzzle.max_riddles_num, 3)
|
|
# jammer 应合并正确答案并去重
|
|
self.assertIn("a1", puzzle.jammer)
|
|
self.assertIn("a2", puzzle.jammer)
|
|
self.assertIn("j1", puzzle.jammer)
|
|
# 初始状态
|
|
self.assertEqual(puzzle.wording, "选择题 - 尚未刷新谜题")
|
|
self.assertEqual(puzzle.answer, ["选择题 - 尚未刷新谜题"])
|
|
self.assertEqual(puzzle.options, [])
|
|
|
|
def test_init_max_riddles_num_clamping(self):
|
|
"""测试 max_riddles_num 限制在 1-5 之间"""
|
|
puzzle1 = MCQPuzzle({}, [], max_riddles_num=0)
|
|
self.assertEqual(puzzle1.max_riddles_num, 1)
|
|
puzzle2 = MCQPuzzle({}, [], max_riddles_num=10)
|
|
self.assertEqual(puzzle2.max_riddles_num, 5)
|
|
|
|
def test_init_jammer_ensures_minimum(self):
|
|
"""测试干扰项至少保证 4 个"""
|
|
puzzle = MCQPuzzle({}, [])
|
|
# 正确答案为空,干扰项为空,应填充空格
|
|
self.assertEqual(len(puzzle.jammer), 4)
|
|
self.assertEqual(set(puzzle.jammer), {" "}) # 三个空格?实际上循环填充空格
|
|
|
|
@patch('random.sample')
|
|
@patch('random.shuffle')
|
|
def test_refresh(self, mock_shuffle, mock_sample):
|
|
"""测试 refresh 方法生成题目"""
|
|
mapping = {"q1": "a1", "q2": "a2", "q3": "a3"}
|
|
jammer = ["j1", "j2", "j3", "j4"]
|
|
puzzle = MCQPuzzle(mapping, jammer, max_riddles_num=2)
|
|
# 模拟 random.sample 返回前两个映射项,以及每个问题的干扰项
|
|
mock_sample.side_effect = [
|
|
[("q1", "a1"), ("q2", "a2")], # 选择问题
|
|
["j1", "j2", "j3"], # 第一个问题的干扰项
|
|
["j1", "j2", "j3"], # 第二个问题的干扰项(可以使用相同的列表)
|
|
]
|
|
puzzle.refresh()
|
|
|
|
# 检查 wording 是列表
|
|
self.assertIsInstance(puzzle.wording, list)
|
|
self.assertEqual(len(puzzle.wording), 2)
|
|
# 检查 answer 列表
|
|
self.assertEqual(puzzle.answer, ["a1", "a2"])
|
|
# 检查 options 列表
|
|
self.assertEqual(len(puzzle.options), 2)
|
|
# 每个选项列表应包含 4 个选项(正确答案 + 3 个干扰项)
|
|
self.assertEqual(len(puzzle.options[0]), 4)
|
|
self.assertEqual(len(puzzle.options[1]), 4)
|
|
# random.shuffle 应被调用
|
|
self.assertEqual(mock_shuffle.call_count, 2)
|
|
|
|
def test_refresh_empty_mapping(self):
|
|
"""测试空 mapping 的 refresh"""
|
|
puzzle = MCQPuzzle({}, [])
|
|
puzzle.refresh()
|
|
self.assertEqual(puzzle.wording, "无可用题目")
|
|
self.assertEqual(puzzle.answer, ["无答案"])
|
|
self.assertEqual(puzzle.options, [])
|
|
|
|
def test_get_question_count(self):
|
|
"""测试 get_question_count 方法"""
|
|
puzzle = MCQPuzzle({"q": "a"}, [])
|
|
self.assertEqual(puzzle.get_question_count(), 0) # 未刷新
|
|
puzzle.refresh = MagicMock()
|
|
puzzle.wording = ["Q1", "Q2"]
|
|
self.assertEqual(puzzle.get_question_count(), 2)
|
|
puzzle.wording = "无可用题目"
|
|
self.assertEqual(puzzle.get_question_count(), 0)
|
|
puzzle.wording = "单个问题"
|
|
self.assertEqual(puzzle.get_question_count(), 1)
|
|
|
|
def test_get_correct_answer_for_question(self):
|
|
"""测试 get_correct_answer_for_question 方法"""
|
|
puzzle = MCQPuzzle({}, [])
|
|
puzzle.answer = ["ans1", "ans2"]
|
|
self.assertEqual(puzzle.get_correct_answer_for_question(0), "ans1")
|
|
self.assertEqual(puzzle.get_correct_answer_for_question(1), "ans2")
|
|
self.assertIsNone(puzzle.get_correct_answer_for_question(2))
|
|
puzzle.answer = "not a list"
|
|
self.assertIsNone(puzzle.get_correct_answer_for_question(0))
|
|
|
|
def test_get_options_for_question(self):
|
|
"""测试 get_options_for_question 方法"""
|
|
puzzle = MCQPuzzle({}, [])
|
|
puzzle.options = [["a", "b", "c", "d"], ["e", "f", "g", "h"]]
|
|
self.assertEqual(puzzle.get_options_for_question(0), ["a", "b", "c", "d"])
|
|
self.assertEqual(puzzle.get_options_for_question(1), ["e", "f", "g", "h"])
|
|
self.assertIsNone(puzzle.get_options_for_question(2))
|
|
|
|
def test_str(self):
|
|
"""测试 __str__ 方法"""
|
|
puzzle = MCQPuzzle({}, [])
|
|
puzzle.wording = "选择题 - 尚未刷新谜题"
|
|
puzzle.answer = ["选择题 - 尚未刷新谜题"]
|
|
self.assertIn("选择题 - 尚未刷新谜题", str(puzzle))
|
|
self.assertIn("正确答案", str(puzzle))
|
|
|
|
puzzle.wording = ["Q1", "Q2"]
|
|
puzzle.answer = ["A1", "A2"]
|
|
str_repr = str(puzzle)
|
|
self.assertIn("Q1", str_repr)
|
|
self.assertIn("A1, A2", str_repr)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main() |