You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何Mock Django ViewFlow中的Handler方法?

解决ViewFlow中Flow方法Mock失败的问题

问题原因

ViewFlow在Django启动时会自动实例化Flow类,而你的do_stuff = flow.Handler(this.do_stuff_handler)代码会在类实例化阶段就绑定了do_stuff_handler的实例方法引用。后续你patch类上的do_stuff_handler时,已经初始化的Handler对象引用的还是原来的绑定方法,所以Mock不会生效。

解决思路及代码示例

1. 直接Patch已实例化Flow对象的Handler引用

ViewFlow通常会把Flow类维护为单例(比如通过MyFlow.instance访问),直接找到这个实例的Handler对象,替换它的回调引用:

from unittest import mock
from django.test import TestCase
from app1.flows import MyFlow

class MyFlowTest(TestCase):
    def test_do_stuff_handler_called(self):
        # 获取已实例化的Flow对象,替换其Handler的handler属性
        with mock.patch.object(MyFlow.instance.do_stuff, 'handler') as mock_handler:
            # 执行触发流程的代码,比如启动流程并走到do_stuff节点
            flow_instance = MyFlow.instance.start.run()
            flow_instance.do_stuff.run()

            # 断言mock被调用
            mock_handler.assert_called_once()

2. 在ViewFlow实例化Flow类前提前Patch

调整测试的导入顺序,确保在ViewFlow加载并实例化MyFlow之前就完成方法Patch:

from unittest import mock

# 先Patch类方法,再导入Flow类
mock_do_stuff = mock.patch('app1.flows.MyFlow.do_stuff_handler').start()

from django.test import TestCase
from app1.flows import MyFlow

class MyFlowTest(TestCase):
    def tearDown(self):
        # 测试结束后停止所有mock
        mock.patch.stopall()

    def test_do_stuff_handler_called(self):
        # 执行流程操作
        flow_instance = MyFlow.instance.start.run()
        flow_instance.do_stuff.run()

        mock_do_stuff.assert_called_once()

3. Patch ViewFlow Handler的执行逻辑

如果前两种方法不适用,可以直接Mock Handler的执行方法,通过断言执行参数来验证目标方法是否被触发:

from unittest import mock
from django.test import TestCase
from app1.flows import MyFlow

class MyFlowTest(TestCase):
    @mock.patch('viewflow.flow.Handler.execute')
    def test_do_stuff_handler_called(self, mock_execute):
        # 执行流程操作
        flow_instance = MyFlow.instance.start.run()
        flow_instance.do_stuff.run()

        # 断言Handler的execute方法被调用,且传入的handler是目标方法
        mock_execute.assert_called()
        call_args = mock_execute.call_args[0]
        self.assertEqual(call_args[0].handler, MyFlow.do_stuff_handler)

内容的提问来源于stack exchange,提问作者James Lin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 04:00:02