Python:如何模拟 SQLAlchemy 事件处理程序(使用 mock.unittest)

标签 python unit-testing event-handling sqlalchemy mocking

所以我有一个带有事件监听器的 SQLAlchemy 模型:

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)

@event.listens_for(User, "after_insert")
@event.listens_for(User, "after_update")
def do_something(mapper, connection, self):
    foo = SomeClass(self)
    foo.do_something_to_database()

我有一个单元测试需要更新/插入模型

@patch('my_package.user.do_something')
def test_user(mock_do_something):
    user = User() # This insert will invoke 'do_something' via the event listener.
    assertSomething(user)

但是,我的测试失败了,因为它似乎仍在调用 do_something 函数并且尚未成功模拟。我尝试阅读如何修补 here (它是在调用这个函数吗?)并且我试图查看 SQLAlchemy 源代码 here找到要修补的适当模块(类似于 @patch('sqlalchemy.event.registrat._listen_fn'))但无济于事。

有没有人遇到过这种情况?

最佳答案

也许有一个删除监听器并在退出时再次添加它的上下文管理器类可以解决问题。

类似于:

class SADeListener(object):
    def __init__(self, class_, event, callable_):
        self.class_ = class_
        self.event = event
        self.callable_ = callable_

    def __enter__(self):
        sqlalchemy.event.remove(self.class_, self.event, self.callable_)

    def __exit__(self, type_, value, tb):
        sqlalchemy.event.listen(self.class_, self.event, self.callable_)

然后直接使用它:

with SADeListener(User, "after_insert", do_something),
   SADeListener(User, "after_update", do_something):
    .. code ...

关于Python:如何模拟 SQLAlchemy 事件处理程序(使用 mock.unittest),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36473283/

相关文章:

unit-testing - 使用 PHPUnit 和 CIUnit 在 CodeIgniter 2 中重定向函数

php - 测试工厂方法

javascript - 在 QUnit 测试中,只有在测试运行之前获得引用时才会触发 click 事件

azure - Azure 应用服务如何决定我的应用程序是事件还是空闲?

python - Unresolved reference 'build' - YouTube Python API

python - Python 2.7 中的 Open() 和 codecs.open() 行为异常不同

python - TensorFlow:为下一批记住 LSTM 状态(有状态 LSTM)

python - 查找活泼的压缩文件

unit-testing - 将模拟 DOM 事件传递给没有 jQuery 的指令处理程序

C++ 事件(焦点)处理