How do you mock a RelatedManager method in Django?

那年仲夏 提交于 2019-12-21 04:51:26

问题


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

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

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.

Does anyone know how to do this?


回答1:


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.

Should end up lookig somthing like:

@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!')

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.



来源:https://stackoverflow.com/questions/12212786/how-do-you-mock-a-relatedmanager-method-in-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!