Dav*_*tom 6 testing django mocking
我有一个Django模型的客户经理,它覆盖了该create方法以保存一些相关对象:
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
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何模拟调用txn.budget_transactions.create以引发异常?
对象的budget_transactions属性txn是.的实例django.db.models.fields.related.RelatedManager.使用mock.patch嘲笑,因为它是动态地宣布这一类不工作-它不能直接进口.
有谁知道如何做到这一点?
您不能将RelatedManager设置为模拟对象的原因是因为django已覆盖对象上的set方法.因此,虽然看起来模拟设置正确,因为没有抱怨,它实际上是静默地设置budget_transactions回RelatedManager.因此,如果您确实需要返回模拟,那么您将需要覆盖返回RelatedManager 的get方法并返回一个模拟对象.
应该最终看起来像:
@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!')
Run Code Online (Sandbox Code Playgroud)
话虽如此,这种方法存在许多缺陷,因为它将覆盖核心django方法,现在ALL RelatedManagers将返回一个模拟对象.从我迄今为止所经历的情况来看,探索其他选择可能更容易.