2012-06-24 8 views
2

Я работаю над модулем Python, который предполагает проверить код SVN и построить его. После многого рефакторинга некоторого унаследованного кода я получил довольно приличное покрытие кода, однако у меня есть зияющая дыра в коде, который использует pysvn.Как насмехаться pysvn

Правда понятие фиктивного объекта является новым для меня, но после прочтения некоторых из документации MiniMock и pymox (оба доступны в моем окружении), я пришел к выводу, что мне нужно будет захватить некоторый вывод pysvn и верните его в свой тестовый код.

Но здесь я нахожусь (помилование каламбур) в маринаде. Объекты, возвращенные из команд pysvn.Client(), не ведут себя хорошо, когда я пытаюсь их рассолить или даже сравнивать.

Любое предложение о том, как сериализовать или иным образом высмеять pysvn или некоторые другие непифонические объекты поведения?

Естественно, я согласен с тем, что я приближаюсь к этой проблеме из-за неправильного направления или что я просто идиот. В этом случае вам помогут любые советы.

Дополнительная информация 0:

Некоторые pysvn объект может быть сведена к dict путем доступа к их data свойства, и могут быть воспроизведены путем пропускания этого dict в соответствующий __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() 
+0

Не могли бы вы подробнее рассказать о том, почему вам нужно рассортировать эти фактические объекты? Может быть достаточно, чтобы вы высмеивали возвращаемое значение из pysvn, а затем утверждали, что cPickle.dumps вызывается с возвращаемым значением. Иногда не стоит углубляться в эту проблему. – aychedee

+0

Извините, я неправильно понял проблему. И мой фактический комментарий был бы, почему вы должны рассортировать эти объекты? Это ограничение вашей издевательской библиотеки? – aychedee

+0

Я не знаю, нужно ли вообще мариновать. Однако мой код обрабатывает возвращаемое значение команд 'pysvn', поэтому мне нужно, чтобы что-то обрабатывало. Я ошибаюсь? –

ответ

2

В этом ответе я использовал minimock, я m на самом деле не знакомы с ним и вместо этого предложили бы использовать 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.

0

Считаете ли вы использование: pickle вместо cPicles? «cPickle модуль в вызываемых объектов Pickler() и Unpickler() являются функции, а не классы. Это означает, что вы не можете использовать их для получения пользовательских засолки и unpickling подклассы.»

Смежные вопросы