【问题标题】:How to mock using sys.modules and with mock.patch (Python interference on static functions)如何使用 sys.modules 和 mock.patch 进行模拟(Python 对静态函数的干扰)
【发布时间】:2020-08-15 00:23:46
【问题描述】:

所以我有这个模拟两次的代码,第一次通过模拟导入:

sys.modules['random'] = MagicMock()

第二次发生在使用该导入的函数的单元测试中,例如使用随机的函数

测试。 py 是:

import sys
import unittest
from unittest import mock
from unittest.mock import MagicMock
import foo

sys.modules['random'] = MagicMock()

class test_foo(unittest.TestCase):

    def test_method(self):
        with mock.patch('random.choice', return_value = 2):
            object = foo.FooClass(3)
            self.assertEqual(2, object.method(), 'Should be 2')

    def test_staticmethod(self):
        with mock.patch('random.choice', return_value = 2):
            object = foo.FooClass(3)
            self.assertEqual(2, object.method(), 'should be 2')

原始文件Foo.py是:

import random

class FooClass:

    def __init__(self,arg):
        self.arg = arg

    def method(self):
        print(random.choice)
        return random.choice([1,2,3])

    @staticmethod
    def staticmethod():
        print(random.choice)
        random.choice([1,2,3])

两个mock相互对立,随机的mock不会发生。 当它随机打印时,它实际上会打印:

<<bound method Random.choice of <random.Random object at 0x7fe688028018>>

我希望它打印一个 MagicMock。 有人可以帮助我了解发生了什么吗?他们为什么互相矛盾?

【问题讨论】:

  • 您能解释一下为什么需要这种双重模拟,以及您的测试中会发生什么吗?此外,您的静态函数中有 self - 可能只是一个错字。
  • 我正在尝试创建自动单元测试,我这样做了两次,一次在开始时尝试模拟导入的库,另一次在适当的内部模拟使用模拟补丁进行单元测试。我知道这可能有问题,但是它适用于除静态功能之外的所有功能。当我在测试中打印模拟对象时,它会随机打印模块,而不是模拟,我不知道为什么它只发生在静态方法中。
  • 嗯,如果您能显示更多代码可能会有所帮助。所以你是说如果你测试静态函数,使用mock.patch 模拟随机是有效的,但是如果你另外模拟sys.modules 它就停止工作了吗?
  • 是的 MrBean,正是这种情况,我编辑了问题以提供更多代码信息
  • 好吧,乍一看,我会说第一次测试中的补丁(更准确地说是结束补丁)正在恢复sys.modules中的原始值,因为它是这样工作的。您可以通过注释掉第一个测试来验证这一点。仍然不清楚为什么首先需要更改 sys.modules

标签: python unit-testing mocking magicmock


【解决方案1】:

您无需使用sys.modules['random'] = MagicMock() 更新模块源代码,没有此行它可以正常工作&lt;MagicMock name='choice' id='...'&gt;patch 已经完成了隔离临时更新方法的所有工作。在文档中查看更多解释 - Where to patch

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 2021-10-04
    • 2016-07-10
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    相关资源
    最近更新 更多