Python 如何模拟pysvn

Python 如何模拟pysvn,python,svn,mocking,tdd,pysvn,Python,Svn,Mocking,Tdd,Pysvn,我正在开发一个Python模块,该模块假设要从SVN签出一些代码并构建它。在对一些遗留代码进行了大量重构之后,我对代码进行了相当不错的覆盖,但是,我使用的代码中有一个很大的漏洞 诚然,Mock对象的概念对我来说是新概念,但在阅读了and的一些文档(两者都在我的环境中可用)后,我得出结论,我需要捕获一些pysvn输出,并将其返回到测试代码中 但在这里,我发现自己(请原谅我的双关语)陷入了困境。当我试图对pysvn.Client()命令返回的对象进行pickle处理,甚至比较它们时,这些对象的行为并

我正在开发一个Python模块,该模块假设要从SVN签出一些代码并构建它。在对一些遗留代码进行了大量重构之后,我对代码进行了相当不错的覆盖,但是,我使用的代码中有一个很大的漏洞

诚然,Mock对象的概念对我来说是新概念,但在阅读了and的一些文档(两者都在我的环境中可用)后,我得出结论,我需要捕获一些pysvn输出,并将其返回到测试代码中

但在这里,我发现自己(请原谅我的双关语)陷入了困境。当我试图对pysvn.Client()命令返回的对象进行pickle处理,甚至比较它们时,这些对象的行为并不好

有没有关于如何序列化或以其他方式模拟pysvn或其他一些非pythonic行为的对象的建议

当然,我愿意接受我从错误的方向处理这个问题,或者我只是一个白痴。在这种情况下,任何建议都会有帮助

附加信息0:

一些
pysvn
对象可以通过访问其
数据
属性而简化为
dict
,并且可以通过将该
dict
传递到相应的
\uuu init\uuu()中来复制

例如:

>>> 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'>

你考虑过用:pickle代替cPicles吗?
“cPickle模块可调用的Pickler()和Unpickler()是函数,而不是类。这意味着您不能使用它们派生自定义pickle和unpickle子类。”

在这个回答中,我使用了minimock,实际上我对它不太熟悉,建议改用minimock。这段代码最终会更干净一些。但您指定了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对象中转储字典。

您可以进一步阐述为什么需要pickle这些实际对象吗?您可以模拟pysvn的返回值,然后断言使用返回值调用cPickle.dumps。有时候不值得深入研究。对不起,我误读了这个问题。我的实际评论是,为什么你要腌制这些东西?这是你的模拟库的限制吗?我不知道我是否需要腌制任何东西。然而,我的代码处理
pysvn
命令的返回值,因此我需要一种方法来处理一些东西。我错了吗?好吧,我在一家严格的TDD商店工作,我很高兴能通过模拟之类的方式进行测试。你能用测试中的代码样本来扩展你的问题吗?只举一个使用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()
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()