嵌套多个依赖项时如何模拟Python类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌套多个依赖项时如何模拟Python类相关的知识,希望对你有一定的参考价值。
如果我有以下架构......
请注意以下编辑。我(在最近的一些重构之后)发现在三个不同的文件中实际上有三个类。对不起,文件/类名变得荒谬了。我向你保证那些不是真名。 :)
main_class.py
class MainClass(object):
def do_some_stuff(self):
dependent_class = DependentClass()
dependent_class.py
class DependentClass(object):
def __init__():
dependent_dependent_class = DependentDependentClass()
dependent_dependent_class.do_dependent_stuff()
dependent_dependent_class.py
class DependentDependentClass(object):
def do_dependent_stuff(self):
print "I'm gonna do production stuff that I want to mock"
print "Like access a database or interact with a remote server"
class MockDependentDependentClass(object):
def do_dependent_stuff(self):
print "Respond as if the production stuff was all successful."
我想在测试期间调用main_class.do_some_stuff
,但是在执行期间,我希望用DependentDependentClass
替换MockDependentDependentClass
的实例,我怎样才能使用最佳实践进行pythonically。
目前,我能想到的最好的事情是根据环境变量的存在/值有条件地实例化一个类或另一个类。它确实有效但很脏。
我花了一些时间阅读有关unittest.mock和mock.patch函数的内容,看起来他们似乎能够提供帮助,但我可以解开的每个描述似乎与我的实际用例略有不同。
关键是我不想定义模拟返回值或属性,但我希望全局更改名称空间,我想,当我的应用程序认为它实例化DependentClass时,它实际上是实例化MockDependentClass。
事实上,我找不到任何人这样做的例子意味着两件事之一:
- 这是因为我是以一种非常愚蠢/天真的方式来做这件事。
- 我正在做一些天才,没有其他人遇到过它。
......我认为它是1号......
完全披露,单元测试不是我熟练的。我的内部工具开发团队正在努力赶上我们的游戏步骤。我可能没有考虑正确测试。
任何想法都会受到欢迎。先感谢您!
解!!!
感谢@ de1的帮助。鉴于我上面显示的聪明架构,以下内容实现了我想要的。
以下代码位于main_class.py
import dependent_class
from dependent_dependent_class import MockDependentDependentClass
with patch.object(dependent_class, "DependentDependentClass", MockDependentDependentClass):
main_class = MainClass()
main_class.do_some_stuff()
代码似乎(并且如果我知道它是如何做的那样)在模块dependent_class
中操作命名空间,以便在with
块内部(这是挂起在该部分上的任何人的上下文管理器)引用该类的任何内容对象DependentDependentClass
实际上将引用MockDependentDependentClass
。
在这种情况下,mock module确实看起来确实很合适。您可以指定在调用各种patch
方法时使用的mock(您的模拟)。
如果只导入类而不是模块,则可以在DependentClass中修补导入的DependentDependentClass:
import .DependentClass as dependent_class
from .DependentDependentClass import MockDependentDependentClass
with patch.object(dependent_class, 'DependentDependentClass', MockDependentDependentClass):
# do something while class is patched
或者:
with patch('yourmodule.DependentClass.DependentDependentClass', MockDependentDependentClass):
# do something while class is patched
或者以下内容仅在您通过模块访问类或在修补后导入类时才有效:
with patch('yourmodule.DependentDependentClass.DependentDependentClass', MockDependentDependentClass):
# do something while class is patched
只是想到什么对象正在修补,何时。
注意:您可能会发现在较小的情况下命名文件时不那么容易混淆,与嵌入式类略有不同。
注意2:如果您需要模拟受测试模块的依赖关系,那么它可能表明您没有在正确的级别进行测试。
以上是关于嵌套多个依赖项时如何模拟Python类的主要内容,如果未能解决你的问题,请参考以下文章
如何使用模块化代码片段中的LeakCanary检测内存泄漏?
spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段