Python撤销方法模拟

18

我正在使用Mock来替换一个类中的方法,并指定返回值。它运行得非常好,甚至有点太好了......我是这样做的(参见下文),但在下一个测试类中,我重新使用了未经模拟的密码类,该测试中放置的模拟仍然有效。

from utils import password as pass_helper

class TestPassword(unittest.TestCase):
    def setUp(self):
        self.username = "user"
        self.password = "Test_1234_pass"
        pass_helper._get_password_from_keyboard = Mock(return_value=self.password)

    def test_password(self):
        password = pass_helper._get_password_from_keyboard(self.username)
        self.assertEqual(password, self.password)

我试图通过类似以下方式在TearDown方法中撤销模拟,但它不起作用。

pass_helper._get_password_from_keyboard = pass_helper._get_password_from_keyboard

我该如何恢复类方法的原始功能?

1个回答

18

就像你已经了解的那样,问题在于你所做的更改不仅限于测试范围,而是会波及到其他测试中(当然,在单元测试中,这是一个大问题)。你考虑在拆卸方法中撤销更改的想法很好,但问题在于你在执行以下操作时将模拟方法的版本重新分配给了它本身:

pass_helper._get_password_from_keyboard = pass_helper._get_password_from_keyboard

可以尝试这样做,即在模拟方法之前将“真实”的方法分配给临时变量:

def setUp(self):
    self.username = "user"
    self.password = "Test_1234_pass"
    self.real_get_password_from_keyboard = pass_helper._get_password_from_keyboard
    pass_helper._get_password_from_keyboard = Mock(return_value=self.password)

def tearDown(self):
    pass_helper._get_password_from_keyboard = self.real_get_password_from_keyboard

def test_password(self):
    password = pass_helper._get_password_from_keyboard(self.username)
    self.assertEqual(password, self.password)

希望这可以帮助到你!


完成这个操作后,我得到了“未绑定的方法xxx必须使用xxx实例作为第一个参数调用(而不是int)”的错误提示。 - Ohad Perry
今天我们遇到了这个问题,尽管它是与MagicMock有关的,但确切地说是相同的“出血”行为。在发现这篇文章之前,我为此苦恼了几个小时。感谢robjohncox! - Francis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接