2012-08-31 23 views
5

私もいくつかの関連するオブジェクトを保存するcreateメソッドをオーバーライドDjangoのモデルのための顧客管理を持っている: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を使用してこのクラスをモックすると、動的に宣言されているので機能しません。直接インポートすることはできません。

誰でもこれを行う方法を知っていますか? Djangoは、オブジェクトに対して方法を設定してオーバーライドしているので、あなただけのモックオブジェクトにRelatedManagerを設定することはできません

+0

Mockライブラリを使用していますか?パッチコンテキストマネージャやデコレータを使いたいですか? – santiagobasulto

+0

この問題を解決できるのであれば、mockライブラリを使用してもよろしいですか?上記のように、従来の方法で 'mock.patch'を使用することは、RelatedManagerクラスの動的宣言のためには機能しません。 – DavidWinterbottom

答えて

5

理由があります。ですから、苦情がなくモックが正しく設定されているように見えますが、実際にはbudget_transactionsをRelatedManagerに静かに設定しています。ですから実際にモックを返す必要がある場合は、getメソッドをオーバーライドして、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

関連する問題