2017-08-04 1 views
0

私はDjangoモデルオブジェクトを(そのメソッドとともに)模擬する方法は?

# utils.py 
def foo_something_exist(): 
    if Foo.objects.get(a='something').exist(): 
     return 'exist' 



# test.py 
import unittest.mock import patch 

import utils 

. 
. 
. 
@patch('utils.Foo') 
def test_foo_something_exist_returns_none(self, mock_foo): 
    mock_foo.objects.get.exists.return_value = False 
    self.assertIsNone(utils.foo_something_exist()) 
. 
. 
. 

test_foo_something_exist()がテストに失敗し、次のようにダミーの方法でチェーンDjangoのモデルオブジェクトを模擬しようとしています。私はutils.pyのFoo.objects.get(a='something').exist()Falseの代わりにMagicMockオブジェクト(<MagicMock name='Member.objects.get().exists()' id='xxxxxx'>)であることを発見しました。これはこのテスト機能の失敗に貢献しました。そして、はい、私はまた投稿に記載されたmock_foo.objects.return_value.get.return_value.exists.return_value = Falseを試しました。モデルオブジェクトを正しく模倣するためのポインタ/ヒント(連鎖したメソッドを使用)は参考になります。

ありがとうございます。

答えて

1

はモデル自体が、model.objectsにパッチを適用して、チェーンのあらゆる部分を模擬しないでください:

@patch('utils.Foo.objects') 
def test_foo_something_exist_returns_none(self, mock_foo): 
    # just to show how to do it with longer chains 
    # mock_foo.filter.return_value = mock_foo 
    # mock_foo.exclude.return_value = mock_foo    
    mock_foo.get.return_value = mock_foo 
    mock_foo.exists.return_value = False 

    self.assertIsNone(utils.foo_something_exist()) 

これも.filter().exclude()および他のモデル事業での仕事します。私はModel MommyがDjangoモデルをテストするときに本当に役に立ちます。

+0

ありがとうございます。 'mock_foo.get.return_value = mock_foo'は何をするのか分かりますか? – tebesfinwo

+0

パッチされたオブジェクトをすべての連鎖メソッド呼び出しの戻り値として使用します。だから、メソッドを持つパッチされたオブジェクトで終わり、それらはすべて同じパッチを当てたオブジェクトを返します。この方法では、メソッド呼び出しをどの順序でチェーンするかは関係ありません。 – masterfloda

関連する問題