pythonモックライブラリを使用して、モデルがDjangoアプリに保存されたときに実行されるCeleryタスクにパッチを適用し、それが正しく呼び出されている。
基本的に、タスクは_myapp.tasks
_内で定義され、次のようにmodels.py-fileの先頭にインポートされます。
_from .tasks import mytask
_
...次に、save()
を使用してモデル内のmytask.delay(foo, bar)
で実行します。これまでのところ良い-実際にセレリッドなどを実行しているときにうまくいきます.
タスクを模倣する単体テストを作成し、正しい引数で呼び出され、実際にCeleryタスクを実行しようとしないことを確認するだけです。
したがって、テストファイルでは、標準のTestCase内に次のようなものが含まれています。
_from mock import patch # at the top of the file
# ...then later
def test_celery_task(self):
with patch('myapp.models.mytask.delay') as mock_task:
# ...create an instance of the model and save it etc
self.assertTrue(mock_task.called)
_
...しかし、呼び出されることはありません/常にfalseです。私はさまざまな化身を試しました(代わりに_myapp.models.mytask
_をパッチし、代わりに_mock_task.delay
_が呼び出されたかどうかを確認しました)インポートパスが重要であることをモックドキュメントから収集しました。テスト中のモジュール内で見られるパス(正しく理解すれば_myapp.models.mytask.delay
_ではなく_myapp.tasks.mytask.delay
_になります)。
ここでどこがいけないのですか?セロリのタスクにパッチを適用する際に特定の問題はありますか?代わりに_celery.task
_(mytask
のデコレータとして使用されます)にパッチを適用できますか?
あなたが抱えている問題は、これがセロリの仕事であるという事実とは無関係です。あなたはたまたま間違ったものにパッチを当てているだけです。 ;)
具体的には、「mytask」をインポートしているビューまたはその他のファイルを見つけ、そこにパッチを適用する必要があるため、関連する行は次のようになります。
with patch('myapp.myview.mytask.delay') as mock_task:
ここにはこれにいくつかの味があります:
http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch
_@task
_デコレータは、関数をTask
オブジェクトに置き換えます( documentation を参照)。タスク自体をモックすると、(やや魔法の)Task
オブジェクトがMagicMock
に置き換わり、タスクはまったくスケジュールされません。代わりに、次のようにTask
オブジェクトのrun()
メソッドをモックします。
_@override_settings(CELERY_ALWAYS_EAGER=True)
@patch('monitor.tasks.monitor_user.run')
def test_monitor_all(self, monitor_user):
"""
Test monitor.all task
"""
user = ApiUserFactory()
tasks.monitor_all.delay()
monitor_user.assert_called_once_with(user.key)
_