我希望这是一个简单的答案,但我一直在努力解决这个问题。我正在模拟以下场景。我以前有过类似的工作:
# path/to/some/module.py
class MyClass:
# None of the methods or init should ever run in a test
def __init__():
pass
def do_thing():
pass
def get_my_class():
return MyClass()
# path/to/some/other/module.py
from path.to.some.module import get_my_class()
def do_something()
get_my_class().do_thing()
return 'something'
# test/path/to/some/other/module.py
from path.to.some.other.module import
def test_do_something():
with patch("path.to.some.module.MyClass") as mock:
assert do_something() = 'something'
mock().do_thing.assert_called_once()
所以这很好 - 断言起作用了,并且没有调用 init 和类方法。但后来我需要改变一些逻辑,现在我无法从嘲笑的角度弄清楚如何让它发挥作用。代码本身有效,我只是无法连续进行模拟。最新结构见下文:
# path/to/some/module.py
class MyClass:
# None of the methods or init should ever run in a test
def __init__():
pass
def do_thing():
pass
class MyClassSingleton:
_my_class = None
def get_my_class():
if MyClassSingleton._my_class is None:
MyClassSingleton._my_class = MyClass()
return MyClassSingleton._my_class
# path/to/some/other/module.py
from path.to.some.module import get_my_class()
def do_something()
get_my_class().do_thing()
return 'something'
我尝试将我的测试更新为:
with patch("path.to.some.module.MyClassSingleton._my_class") as mock:
但这会导致
MyClass.__init__
代码运行,这可不是什么好事。
我的目标是从模拟的角度来看,一切都或多或少地像以前一样工作,理想情况下使用尽可能简单的设置/样板,因为我需要将这些更改应用于数百个测试。任何帮助,将不胜感激。谢谢!
patch('path.to.some.module.MyClassSingleton._my_class')
已经是MyClass的一个实例,所以问题是在assert_called_once
中调用mock().do_thing
,你应该在mock.do_thing
中调用它。
def test_do_something():
with patch('path.to.some.module.MyClassSingleton._my_class') as mock:
assert do_something() == 'something'
mock.do_thing.assert_called_once()