2010-08-10 4 views
5

Я пишу некоторые модульные тесты (используя модуль unittest) для своего приложения и хочу написать что-то, что может проверить, что метод, который я вызываю, возвращает объект, подобный файлу. Поскольку это не простой вызов, мне интересно, какая лучшая практика для определения этого?Python: определение того, является ли объект файлоподобным?

Так, в общих чертах:

possible_file = self.dao.get_file("anotherfile.pdf") 
self.assertTrue(possible_file is file-like) 

Возможно, я должен заботиться, какой именно интерфейс этого файл объект реализует, или какие методы, которые делают его файл, как я хочу, чтобы поддержать?

Спасибо,

R

ответ

2

Проверить, если возвращаемый объект предоставляет интерфейс, который вы ищете. Как это, например:

self.assert_(hasattr(possible_file, 'write')) 
self.assert_(hasattr(possible_file, 'read')) 
+1

Не делайте этого, если вы не являетесь _sure_, что хотите этого. – katrielalex

+0

Да, я бы этого не сделал. Но он попросил способ проверить, если что-то вроде файла, а не использовать его в качестве файла. – gruszczy

4

классический менталитет Python, что это легче просить прощения, чем разрешения. Другими словами, не проверяйте, не поймайте исключение, вызванное write.

Новый способ заключается в использовании IO abstract base class в isinstance чек. Это было введено, когда люди поняли, что утиная печать является удивительной, но иногда вам действительно нужна проверка экземпляра.

В вашем случае (модульное тестирование), вы, вероятно, хотите, чтобы попробовать и посмотреть:

thingy = ... 
try: 
    thingy.write(...) 
    thingy.writeline(...) 
    ... 
    thingy.read() 
except AttributeError: 
    ... 
+2

попытка записи в файл может оказаться неприемлемой в контексте единичного теста. –

+0

+1 для моделей классического и ренессансного мышления –

+0

@Ned: действительно? Если вы реализуете файлоподобный класс, вы должны проверить, что он * записывает то, что вы ему даете? Но если вы действительно этого не хотите, вы можете использовать 'hasattr'. – katrielalex

7

Там нет «официального определения» о том, что объекты «достаточно файл типа», так как при различных видах использования файловые объекты имеют такие разные требования, например, некоторые требуют только read или write методов, другие требуют некоторого подмножества различных методов чтения строк ... все способы для некоторых, требующие метода fileno, который даже не может быть поставляемый «очень файлоподобными объектами», предлагаемый модулями StringIO и cStringIO в стандартной библиотеке. Это определенно вопрос «оттенков серого», не черно-белая таксономия!

Итак, вам необходимо определить, какие методы вам необходимо. Чтобы проверить их, я рекомендовал определить ваши собственные FileLikeEnoughForMe с декораторами abstractmethod и проверить объект с помощью isinstance для этого класса, если вы на Python 2.6 или выше: это рекомендуемая идиома в наши дни, а не куча hasattr проверок, которые были бы менее читабельными и более сложными (при правильной настройке с проверками, что эти атрибуты фактически являются методами и т. Д .;-).

+0

Привет, Алекс, Спасибо за указатель, это интересный материал, хотя я все еще обнимаю его. Вы предлагаете просто использовать это для unittest или это должен быть общий подход к управлению файлоподобными объектами внутри приложения? –

+0

@ Рихард, я едва «мочу себя» сам по себе с использованием ABC в Python (хотя аналогия с классными классами Haskell, абстрактными базовыми классами C++, интерфейсами Java и т. Д., Мне помогают ;-), поэтому я могу " t (пока) твердо рекомендуют их или иным образом в этом контексте. Я думаю, что все будет хорошо (опять же по аналогии с альтернативами, которые я очень хорошо знаю), но мне нужно немного больше по-настоящему драться с ними «под моим поясом», чтобы чувствовать себя действительно уверенно в любом случае ;-). Но для целей тестирования я уже не знаю, что они «пижама кошки», то есть отлично и полезно. –

+0

arg - нет разметки кода в комментариях! –

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