2016-05-20 13 views
1

私はdatashape Pythonパッケージを使用しており、@datashape.discover.registerデコレータで新しいタイプを登録しています。私はdatashape.discoverを登録しているオブジェクトに呼び出すと、装飾されている関数を呼び出していることをテストしたいと思います。また、実際に装飾されている機能を実行していないことを意味する良いユニットテストの原則でこれを実行したいと思います。テストでは望ましくない副作用があるためです。しかし、これは動作していません。デコレータによって登録されたメソッドをPythonのdatashapeにどのようにパッチするのですか?

はここで、問題を示すために、いくつかのサンプルコードです:

myfile.py:

@datashape.discover.register(SomeType) 
def discover_some_type(data) 
    ...some stuff i don't want done in a unit test... 

test_myfile.py:

class TestDiscoverSomeType(unittest.TestCase): 
    @patch('myfile.discover_some_type') 
    def test_discover_some_type(self, mock_discover_some_type): 
     file_to_discover = SomeType() 

     datashape.discover(file_to_discover) 

     mock_discover_some_type.assert_called_with(file_to_discover) 

問題は、私が欲しい機能が嘲笑ことのようですテストの体で嘲笑されていますが、それが装飾されたとき(つまり輸入されたとき)には嘲笑されませんでした。 discover.register関数は、指定された型の引数でdiscover()が呼び出されると、装飾されている関数を本質的に内部的に登録して調べます。残念ながら、は実際にの機能を登録していますが、パッチしたバージョンではないので、常にという機能が呼び出されます。

装飾されている関数にパッチを当てる方法について考えて、datashape.discoverが呼び出されたときに呼び出されると主張しますか?

sometype.py:

def discover_some_type(data): 
    ...some stuff i don't want done in a unit test... 

discovery_channel.py:

import sometype 

@datashape.discover.register(SomeType) 
def discover_some_type(data): 
    return sometype.discover_some_type(data) 

test_sometype.py:

ここ

答えて

1

はそれが少しだけハックです私が見つけたソリューションです
class TestDiscoverSomeType(unittest.TestCase): 
    @patch('sometype.discover_some_type') 
    def test_discover_some_type(self, mock_discover_some_type): 
     import discovery_channel 

     file_to_discover = SomeType() 

     datashape.discover(file_to_discover) 

     mock_discover_some_type.assert_called_with(file_to_discover) 

鍵は、実際に何をするかをパッチしなければならないということです。の前にには、パッチされた機能をdatashapeに登録する装飾機能を持つモジュールをインポートします。これは残念なことに、あなたが装飾された機能と同じモジュール内の発見を行う機能を持つことができないということを意味します(論理的にまとめるべきものが今や離れている)。そしてユニットテストでは、(discover.registerをトリガするための)ややハッキリな機能のインポートがあります。しかし少なくともそれはを働かせます。

+1

まったくハッキーではありません。私の好みは 'mock.patch'をコンテキストマネージャーとして使用することです。つまり、with patch(...):ブロックの中でインポートを行うことを意味します。 –

関連する問題