【问题标题】:How do you change the output of mocked methods, using the Mock framework?如何使用 Mock 框架更改模拟方法的输出?
【发布时间】:2012-04-19 10:25:32
【问题描述】:

我有一个类似如下的模块:

'''example.py'''
from some.module import Session

def init_system():
    var_one = Session.query(SQLAModelA).all()
    var_two = [(x.attr_B_a, x) for x in Session.query(SQLAModelB).all()]

    for value in var_one:
        something = value.attr_A_a + value.attr_A_c
    # Will do something with var_two etc (which has different attributes)
    something_else = [x.attr_B * 2 for x in var_two]
    return result

Session 是指与 DB 对话的 SQLAlchemy 会话处理程序。出于测试目的,我需要能够模拟 Session 对象(或者可能只是 Session 对象?)中的查询方法,这样我就可以测试 init_system 而无需它实际与数据库交互。如何使用Mock framework 来执行此操作?

真正让我感到困惑的是,如果我模拟query() 方法,我该如何更改依赖于传递给query() 的类的所有方法的输出??

我希望我能做一些类似的事情:

def test_init_numbers():
    import
    my_mock_object = MagicMock()
    with patch('some.module.Session.query', my_mock_object):
        result = example.init_system()
        assert result == ['expected', 'result']

但是,我不知道我需要对 my_mock_object 做什么才能使其正确模仿 query()。我猜它需要实现返回迭代器的all() 方法。而且,我知道我可以在返回的迭代器中创建更多的模拟对象,确保它们具有适当属性的值,例如:

var_one_element_mock = MagicMock(spec=SQLAModelA)
var_one_element_mock.attr_A_a = 12

var_two_element_mock = MagicMock(spec=SQLAModelB)
var_one_element_mock.attr_B = 100

当然,我可以创建可被 init_system 函数使用的 MagicMock 对象的不同版本的迭代,例如,在 for value in var_one 行中。

但我不知道如何将所有模拟对象拼凑在一起,所以我可以模拟 Session.query 方法,同时考虑到一个类被传递给它,这会影响它返回的可迭代对象的内容。

谢谢!

【问题讨论】:

    标签: python unit-testing mocking sqlalchemy python-mock


    【解决方案1】:

    我不知道你是否还需要这方面的帮助,但如果你想控制调用 MagicMock 对象时发生的事情,你可以传递一个函数作为它的 side_effect 参数。 这样的事情应该可以工作。

    def test_init_numbers():
        import
        my_mock_object = MagicMock()
        def return_iterator():
          ## create and return your iterator here
    
        my_mock_object.all = MagicMock(side_effect=return_iterator)
        with patch('some.module.Session.query', my_mock_object):
            result = example.init_system()
            assert result == ['expected', 'result']
    

    【讨论】:

    • 感谢您的回答。这很有用,但我认为问题仍然在于区分副作用迭代器的输出,具体取决于传递给query() 的类的类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多