简体   繁体   English

如何在python中模拟链接的函数调用?

[英]How to mock chained function calls in python?

I'm using the mock library written by Michael Foord to help with my testing on a django application. 我正在使用由Michael Foord编写的模拟库来帮助我在Django应用程序上进行测试。

I'd like to test that I'm setting up my query properly, but I don't think I need to actually hit the database, so I'm trying to mock out the query. 我想测试一下我是否正确设置了查询,但是我认为不需要实际访问数据库,因此我试图模拟查询。

I can mock out the first part of the query just fine, but I am not getting the results I'd like when I chain additional things on. 我可以很好地模拟出查询的第一部分,但是当我附加其他内容时,却没有得到想要的结果。

The function: 功能:

@staticmethod
    def get_policies(policy_holder, current_user):
        if current_user.agency:
            return Policy.objects.filter(policy_holder=policy_holder, version__agency=current_user.agency).distinct()
        else:
            return Policy.objects.filter(policy_holder=policy_holder)

and my test: The first assertion passes, the second one fails. 和我的测试:第一个断言通过,第二个断言失败。

def should_get_policies_for_agent__user(self):
        with mock.patch.object(policy_models.Policy, "objects") as query_mock:
            user_mock = mock.Mock()
            user_mock.agency = "1234"
            policy_models.Policy.get_policies("policy_holder", user_mock)
            self.assertEqual(query_mock.method_calls, [("filter", (), {
                'policy_holder': "policy_holder",
                'version__agency': user_mock.agency,
            })])
            self.assertTrue(query_mock.distinct.called)

I'm pretty sure the issue is that the initial query_mock is returning a new mock after the .filter() is called, but I don't know how to capture that new mock and make sure .distinct() was called on it. 我很确定问题是在调用.filter()之后,初始的query_mock返回一个新的模拟,但是我不知道如何捕获该新的模拟并确保调用了.distinct()。

Is there a better way to be testing what I am trying to get at? 有没有更好的方法来测试我要达到的目标? I'm trying to make sure that the proper query is being called. 我试图确保正在调用正确的查询。

Each mock object holds onto the mock object that it returned when it is called. 每个模拟对象都保留调用时返回的模拟对象。 You can get a hold of it using your mock object's return_value property. 您可以使用模拟对象的return_value属性来保留它。

For your example, 例如,

self.assertTrue(query_mock.distinct.called)

distinct wasn't called on your mock, it was called on the return value of the filter method of your mock, so you can assert that distinct was called by doing this: 在您的模拟中未调用distinct,而是在模拟的filter方法的返回值上调用了它,因此您可以断言通过以下操作调用了distinct:

self.assertTrue(query_mock.filter.return_value.distinct.called)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM