7

a()同じモジュールで定義された別の関数を呼び出す( call it ) 関数を持つモジュールがあります ( call it __b())。 __b()経由で Web サイトurllib2と通信し、データを取得する機能です。今、私は をテストしようとしていますa()が、もちろん、単体テストで公共のインターネットと通信したくありません。__b()したがって、定型データを返す関数でモンキー パッチを適用できれば、のテストを記述できると考えていますa()

より具体的に言うと、私のモジュールは次のようになります。

def a():
    return __b("someval")

def __b(args):
    return something_complex_with_args

だから今私はテストしたいのですa()が、パッチを適用する必要があり__bます。問題は、A) モンキー パッチに関する情報のほとんどが、モジュール内の関数ではなく、クラスのメソッドに適用されること、および B) モンキー パッチを適用する関数がプライベートであることです。__bプロセスがより実現可能になるのであれば、私は非公開に変更しても構わないと思っていますが、そうはなりません。

提案?

編集:現状では、テストクラスは次のようになります。

from unittest import TestCase

import mymodule

def newfn(args):
    return {"a" : "b"}

mymodule._b = newfn

class TestMyModule(TestCase):
    def test_basic(self):
        print(mymodule.a('somearg'))

これを実行すると、出力が表示されるのではなく、サルのパッチがまったく適用されていない場合の出力が表示{'a': 'b'}されます。

4

3 に答える 3

2

モジュールの名前が「foo」の場合、次のように動作するはずです。

import foo

def patched_version():
    return 'Hello'

foo.__b = patched_version

print (foo.a())

foo.py の場所

def a():
    return __b()

def __b():
    return 'Goodbye'
于 2012-12-26T21:52:13.963 に答える
0

私は同じ問題に直面していましたが、最終的に解決策にたどり着きました。unittest.TestCase クラスでモンキー パッチを使用するときに問題が発生しました。うまく機能するソリューションは次のとおりです。

Python 2 を使用している場合は、easy_install またはその他の方法を使用して「モック」ライブラリ (http://www.voidspace.org.uk/python/mock/) をインストールする必要があります。このライブラリはすでに Python 3 にバンドルされています。

コードは次のようになります。

from mock import patch

    class TestMyModule(TestCase):
        def test_basic(self):
            with patch('mymodule._b') as mock:
                mock.return_value={"a" : "b"} # put here what you want the mock function to return. You can make multiple tests varying these values.
                #keep the indentation. Determines the scope for the patch.
                print(mymodule.a('somearg'))

この方法は、さまざまな引数に基づいてさまざまな値を返すロジックを持つ実際のサブ関数 _b() を模倣できるモック関数を作成する場合に比べて少し不便に思えますが、不必要にエラーの可能性を増やします。このアプローチでは、モック化された関数が返すものをハードコーディングし、テストしようとしている実際の関数、つまり a() をテストするだけです。

于 2013-01-22T10:12:56.427 に答える