web-dev-qa-db-ja.com

Djangoモデルオブジェクト(およびそのメソッド)をモックする方法は?

私はチェーンされた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()はテストに失敗します。 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_も試しました。モデルオブジェクトを(チェーンされたメソッドとともに)正しくモックするためのポインター/ヒントは高く評価されます。

前もって感謝します。

11
tebesfinwo

モデル自体にパッチを適用するのではなく、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モデルを見つけます。

14
masterfloda