2

私は、SVN からいくつかのコードをチェックアウトしてビルドすることを想定した Python モジュールに取り組んでいます。いくつかのレガシー コードを何度もリファクタリングした後、コードをかなり適切にカバーできましたが、 pysvnを使用するコードに大きな穴があります。

確かに、Mock オブジェクトの概念は私にとって新しいものですが、MiniMockpymoxのドキュメントをいくつか読んだ後(私の環境ではどちらも利用可能です)、pysvn の出力をキャプチャしてそれを返す必要があるという結論に達しました。私のテストコード。

しかし、ここで私はピクルスの中にいることに気づきます(駄洒落を許してください)。pysvn.Client() コマンドから返されたオブジェクトは、それらをピクルしようとしても、比較しようとしてもうまく動作しません。

pysvn またはその他の非 Pythonic 動作オブジェクトをシリアル化またはモックする方法の提案はありますか?

当然のことながら、私はこの問題に間違った方向から取り組んでいること、または私が単なる馬鹿であることを喜んで受け入れます。その場合、どんなアドバイスも役に立ちます。

追加情報 0:

一部のpysvnオブジェクトは、そのプロパティにdictアクセスすることで に縮小でき、これを適切なdatadict__init__()

例えば:

>>> svn=pysvn.Client()
>>> svn.list('http://svn/svn/')[0][0]
<PysvnList u'http://svn/svn'>
>>> d=svn.list('http://svn/svn/')[0][0].data
>>> pysvn.PysvnList(d)
<PysvnList u'http://svn/svn'>

ただし、このオブジェクト内には、ピクルできないオブジェクトがいくつかある可能性があります。

>>> cPickle.dumps(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
cPickle.UnpickleableError: Cannot pickle <type 'node_kind'> objects

追加情報 1:

@HについてはDunlopのリクエストです。これは私のコードの (簡略化された) スニペットです。SVN からリストを取得し、ユーザーがそのリストから項目を選択できるようにします。

class Menu(object):
    """a well covered class"""
    # ...

class VersionControl(object):
    """A poorly covered class"""

    def __init__(self):
        self.svn = pysvn.Client()

    # ...

    def list(self, url):
        """svn ls $url"""
        return [os.path.basename(x['path']) for (x,_) in self.svn.list(url)[1:]]

    def choose(self, choice, url):
        """Displays a menu from svn list, and get's the users choice form it.

        Returns the svn item (path).
        """
        menu = Menu(prompt="Please choose %s from list:\n" % choice,
                    items=self.list(url),
                    muliple_choice=False)
        menu.present()
        return menu.chosen()
4

2 に答える 2

2

この回答では、ミニモックを使用しましたが、実際にはあまり慣れていないため、代わりにhttp://www.voidspace.org.uk/python/mock/を使用することをお勧めします。このコードは少しきれいになります。しかし、minimock または pymox を指定したので、次のようになります。

from minimock import TraceTracker, Mock, mock
import unittest

import pysvn

from code_under_test import VersionControl


class TestVersionControl(unittest.TestCase):


    def test_init(self):

        mock_svn = Mock(name='svn_client')
        mock('pysvn.Client', returns=mock_svn)

        vc = VersionControl()

        self.assertEqual(vc.svn, mock_svn)


    def test_list_calls_svn_list_and_returns_urls(self):

        tracker = TraceTracker()
        test_url = 'a test_url'
        mock_data = [
            ({'path': 'first result excluded'}, None),
            ({'path': 'url2'}, None),
            ({'path': 'url3', 'info': 'not in result'}, None),
            ({'path': 'url4'}, None),
        ]

        vc = VersionControl()
        mock('vc.svn.list', returns=mock_data, tracker=tracker)

        response = vc.list(test_url)
        self.assertEqual(['url2', 'url3', 'url4'], response)
        self.assertTrue("Called vc.svn.list('a test_url')" in tracker.dump())


if __name__ == '__main__':
    unittest.main()

pysvn によって返された基になる辞書をさらにテストしたい場合は、タプルのリストを変更して、その中に辞書を返すようにすることができます。pysvn オブジェクトから辞書をダンプしただけのコードを少し書くこともできます。

于 2012-07-03T00:20:40.767 に答える
0

cPicles の代わりに pickle の使用を検討しましたか? " cPickle モジュールの callable Pickler() と Unpickler() は関数であり、クラスではありません。つまり、それらを使用して、カスタムの pickling および unpickling サブクラスを派生させることはできません。 "

于 2012-07-02T22:43:32.233 に答える