Python-如何模拟多个类方法

时间:2019-05-01 10:15:16

标签: python python-unittest python-mock python-behave

我正在子类中编写一个新方法。该方法将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())

0 个答案:

没有答案