2012-08-31 37 views
5

我有一個客戶經理一個Django模型,覆蓋create方法還可以節省一些相關的對象:你如何模擬Django中的RelatedManager方法?

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引發異常?

txn對象的budget_transactions屬性是django.db.models.fields.related.RelatedManager的一個實例。使用mock.patch來模擬這個類不能工作,因爲它是動態聲明的 - 它不能直接導入。

有誰知道如何做到這一點?

+0

你使用模擬庫嗎?你想使用補丁上下文管理器或修飾器嗎? – santiagobasulto

+0

如果能解決這個問題,我很樂意使用模擬庫。正如我上面所述,由於RelatedManager類的動態聲明,以傳統方式使用'mock.patch'不起作用。 – DavidWinterbottom

回答

5

您不能只將RelatedManager設置爲模擬對象的原因是因爲django已經覆蓋了對象的集合方法。所以雖然看起來模擬的設置是正確的,因爲沒有任何投訴,但實際上是悄悄地將budget_transactions設置回相關管理器。所以如果你真的需要返回一個模擬,那麼你需要重寫獲取方法,該方法返回RelatedManager並返回一個模擬對象。

應該結束了lookig財產以後這樣的:

@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會返回一個嘲笑對象。從我迄今爲止所經歷的情況來看,探索其他選擇可能更容易。

+0

我不得不嘲笑'django.db.models.fields.related.ReverseManyRelatedObjectsDescriptor .__ set__',但方法相同。 – AlanSE

相關問題