我正在子类中编写一个新方法。该方法将json对象发布到MQTT代理上,并对来自客户端的响应进行计时。 为了对其进行单元测试,我想修补发布json消息的方法(由被测方法调用)并设置响应时间。 没有模拟能力,将依赖于现有的MQTT代理和客户端来发布响应。另一个原因是要对被测试方法传递给模拟方法的参数(json对象)进行内省。 到目前为止,我已经可以修补类的 init 方法,因为这可以初始化许多不需要的东西来测试我的方法(记录器,配置文件等)。但是,当我尝试在同一类上修补另一种方法时。被测方法调用的是真正的发布方法,而不是模拟方法。 我正在使用python 2.7(不是通过选择)。 我使用行为作为单元测试框架。
我有一个要进行单元测试的功能,它依赖于运行每种方案的相似上下文。因此,在environment.py(类似于pytest的confest.py)中,我实例化了一次类,以贯穿整个功能。这很好。当我向“ publish_json”方法添加另一个补丁时。因为没有运行MQTT代理,所以它将调用real方法并失败。
我还尝试在测试步骤实现文件中使用MagicMock模拟'publish_json'方法。但是,这返回了一个不包含任何参数的call()对象。
类的结构。
BaseClass
__init__ which i've successfully patched.
contains the publish_json which i'm unable to patch.
aSubClass(BaseClass)
containing derived functionality
anotherSubClass(aSubClass)
containing the new method to test.
will eventually use the functionality within the parent classes.
# environment.py...
from anotherSubClass import anotherSubClass
def fake_pub():
print("the fake json publisher has been called!!!")
return True
@fixture
def anotherSubClass_mocked(context):
# pacthing out the base class initialisation
# patching the publish_json method which isn't working
with patch.object(anotherSubClass, "__init__", lambda x,y,z: None), patch.object(anotherSubClass, "publish_json", fake_pub):
context.tester = anotherSubClass(None,None)
# steps.py
@when(u'the tester sends a START message')
def step_impl(context):
# patch the publish_json call here and validate the json contents (call_args)
context.tester.publish_json = Mock()
context.tester.time_mqtt_msg("START")
args = context.tester.publish_json.call_args()
# method under test
from aSubClass import aSubClass
class anotherSubClass(aSubClass):
def time_cloud_msg(self, msg, timeout=10):
mqtt_msg = {"msg":"TEST", "time": self.generate_timestamp()}
print("Sending message to remote broker")
self.publish_json("remote", "command", mqtt_msg)
# timer not yet implemented... :-(
期待要调用的假json发布者。 在第一个实例中(在环境中),实际的发布方法称为 在第二种情况下(分步执行),该模拟程序被认为没有调用(call())