您如何在Django中模拟RelatedManager方法? [英] How do you mock a RelatedManager method in Django?

查看:63
本文介绍了您如何在Django中模拟RelatedManager方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Django模型的客户经理,该模型重写了create方法,还保存了一些相关对象:

I have a customer manager for a Django model which overrides the create method to also save some related objects:

class CustomManager(models.Manager):
    def create(self, amount, user, description):
        txn = self.get_query_set().create(user, description)
        txn.budget_transactions.create(amount)
        return txn

我的问题是:如何模拟对txn.budget_transactions.create的调用以引发异常?

My question is: how do I mock the call to txn.budget_transactions.create to raise an exception?

txn对象的budget_transactions属性是django.db.models.fields.related.RelatedManager的实例.使用mock.patch模拟该类无效,因为它是动态声明的-不能直接导入.

The budget_transactions attribute of the txn object is an instance of django.db.models.fields.related.RelatedManager. Using mock.patch to mock this class doesn't work as it is declared dynamically - it can't be imported directly.

有人知道该怎么做吗?

推荐答案

不能将RelatedManager设置为模拟对象的原因是django覆盖了该对象的 set 方法.因此,尽管似乎没有任何抱怨,因此正确设置了模拟,但实际上它是在默默地将budget_transactions设置回RelatedManager.因此,如果您确实需要返回模拟,则需要重写 get 方法,该方法返回RelatedManager并返回模拟对象.

The reason that you can't just set the RelatedManager to a mock object is because django has overridden the set method on the object. So while it appears that the mock is getting set correctly because there are no complaints, it's actually silently setting budget_transactions back to the RelatedManager. So if you really need to return a mock then you'll need to override the get method that returns the RelatedManager and return a mocked object instead.

最终应该像:

@mock.patch('django.db.models.fields.related.ForeignRelatedObjectsDescriptor.__get__')
def test_campaign_cancel(self, mock_manager):
    mock_manager.return_value = mock.MagicMock()
    mock_manager.return_value.create = Exception('Boom!')

话虽这么说,这种方法有很多陷阱,因为它将覆盖核心的django方法,现在 ALL RelatedManagers将返回一个模拟对象.从到目前为止的经验来看,探索其他选择可能更容易.

That being said there are many pitfalls to this approach since it will be overriding a core django method and now ALL RelatedManagers will return a mocked object. From what I have experienced so far it's probably easier to explore other options.

这篇关于您如何在Django中模拟RelatedManager方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆