1. ホーム
  2. python

[解決済み] Python Mockを使った関数のモッキング

2023-04-19 16:10:11

質問

私は Mock を使って、(外部のコンテンツを返す)関数を作ろうとしています。 モックモジュール .

モジュールにインポートされた関数をモックするのに苦労しています。

例えば util.py には

def get_content():
  return "stuff"

モックを作りたい util.get_content をモックして、他のものを返すようにしたい。

私はこれを試しています。

util.get_content=Mock(return_value="mocked stuff")

もし get_content が別のモジュールの中で呼び出された場合、実際にはモックされたオブジェクトを返すことはないようです。を使用する方法について、私は何かを見逃しているのでしょうか? Mock ?

なお、以下のように呼び出すと、正常に動作します。

>>> util.get_content=Mock(return_value="mocked stuff")
>>> util.get_content()
"mocked stuff"

しかし、もし get_content が他のモジュール内部から呼び出された場合、モック化されたバージョンではなく、オリジナルの関数を呼び出します。

>>> from mymodule import MyObj
>>> util.get_content=Mock(return_value="mocked stuff")
>>> m=MyObj()
>>> m.func()
"stuff"

の内容は mymodule.py

from util import get_content

class MyObj:    
    def func():
        get_content()

そこで質問なのですが、呼び出したモジュールの内部からモック版の関数を呼び出すにはどうしたらよいのでしょうか?

どうやら from module import function がモック関数を指していないことが原因である可能性があります。

どのように解決するのですか?

一般的なケースを解決する方法はまだ明確ではありませんが、私は回避策を持っていると思います。

mymodule に置き換えた場合

from util import get_content

class MyObj:    
    def func():
        get_content()

import util

class MyObj:    
    def func():
        util.get_content()

Mock が呼び出されるようです。名前空間が一致する必要があるようです (これは理にかなっています)。しかし、奇妙なことに、私が期待するのは

import mymodule
mymodule.get_content = mock.Mock(return_value="mocked stuff")

を使えば、from/import 構文を使っている元のケースでトリックを行うことができます(現在では、この構文で get_contentmymodule ). しかし、これはまだモックされていない get_content .

名前空間が重要であることがわかりました - ただ、コードを書くときにそれを心に留めておく必要があります。