나는 이것을 거의 2 시간 동안 아무런 노력없이 시도하고 있습니다.Python에서 ImportError를 조롱하십시오.
나중에 코드에서try:
from zope.component import queryUtility # and things like this
except ImportError:
# do some fallback operations <-- how to test this?
:
try:
queryUtility(foo)
except NameError:
# do some fallback actions <-- this one is easy with mocking
# zope.component.queryUtility to raise a NameError
어떤 아이디어
나는 다음과 같다 모듈이 있나요?편집 :
알렉스의 제안이 작동하지 않는 것 : 나는 실행할 때 가하는, 일을하지만
[email protected] ~/work/ao.shorturl $ ./bin/test --coverage .
Running zope.testing.testrunner.layer.UnitTests tests:
Set up zope.testing.testrunner.layer.UnitTests in 0.000 seconds.
Error in test /home/aatiis/work/ao.shorturl/src/ao/shorturl/shorturl.txt
Traceback (most recent call last):
File "/usr/lib64/python2.5/unittest.py", line 260, in run
testMethod()
File "/usr/lib64/python2.5/doctest.py", line 2123, in runTest
test, out=new.write, clear_globs=False)
File "/usr/lib64/python2.5/doctest.py", line 1361, in run
return self.__run(test, compileflags, out)
File "/usr/lib64/python2.5/doctest.py", line 1282, in __run
exc_info)
File "/usr/lib64/python2.5/doctest.py", line 1148, in report_unexpected_exception
'Exception raised:\n' + _indent(_exception_traceback(exc_info)))
File "/usr/lib64/python2.5/doctest.py", line 1163, in _failure_header
out.append(_indent(source))
File "/usr/lib64/python2.5/doctest.py", line 224, in _indent
return re.sub('(?m)^(?!$)', indent*' ', s)
File "/usr/lib64/python2.5/re.py", line 150, in sub
return _compile(pattern, 0).sub(repl, string, count)
File "/usr/lib64/python2.5/re.py", line 239, in _compile
p = sre_compile.compile(pattern, flags)
File "/usr/lib64/python2.5/sre_compile.py", line 507, in compile
p = sre_parse.parse(p, flags)
AttributeError: 'NoneType' object has no attribute 'parse'
Error in test BaseShortUrlHandler (ao.shorturl)
Traceback (most recent call last):
File "/usr/lib64/python2.5/unittest.py", line 260, in run
testMethod()
File "/usr/lib64/python2.5/doctest.py", line 2123, in runTest
test, out=new.write, clear_globs=False)
File "/usr/lib64/python2.5/doctest.py", line 1351, in run
self.debugger = _OutputRedirectingPdb(save_stdout)
File "/usr/lib64/python2.5/doctest.py", line 324, in __init__
pdb.Pdb.__init__(self, stdout=out)
File "/usr/lib64/python2.5/pdb.py", line 57, in __init__
cmd.Cmd.__init__(self, completekey, stdin, stdout)
File "/usr/lib64/python2.5/cmd.py", line 90, in __init__
import sys
File "<doctest shorturl.txt[10]>", line 4, in fakeimport
NameError: global name 'realimport' is not defined
:
>>> import __builtin__
>>> realimport = __builtin__.__import__
>>> def fakeimport(name, *args, **kw):
... if name == 'zope.component':
... raise ImportError
... realimport(name, *args, **kw)
...
>>> __builtin__.__import__ = fakeimport
이 테스트를 실행하는 경우 파이썬 대화 형 콘솔에서 동일한 코드.
더 편집 : 나는 zope.testing
을 사용하고
내 모듈의이 부분에 고유 한 모든 테스트가 테스트 파일, shorturl.txt
. 먼저 zope.component
모듈을 가져 와서 &의 일반적인 사용법을 테스트합니다. zope.*
패키지가 없으면 가장자리 케이스로 간주되므로 나중에 테스트 할 것입니다. 따라서, 내 모듈 zope.*
을 사용할 수 없게 된 후, 어떻게 든.
지금까지 난 다음 sys.path[0]
에 TEMPDIR를 삽입하고, sys.modules
에서 이전 zope.*
패키지를 제거의 TEMPDIR에 tempfile.mktempdir()
빈 zope/__init__.py
및 zope/component/__init__.py
파일을 사용하려고했습니다.
작동하지 않았습니다.
더 편집 : 한편
, 나는이 시도했다 :
>>> class NoZope(object):
... def find_module(self, fullname, path):
... if fullname.startswith('zope'):
... raise ImportError
...
>>> import sys
>>> sys.path.insert(0, NoZope())
을 그리고 그것은 테스트 스위트의 네임 스페이스에 대해 잘 작동 (= shorturl.txt
의 모든 수입) ,하지만 내 메인 모듈에서 실행되지 않습니다 ao.shorturl
. 심지어 내가 reload()
일 때. 왜 그런가? zope.interfaces
가져 오기
>>> import zope # ok, this raises an ImportError
>>> reload(ao.shorturl) <module ...>
는 ImportError
을 제기, 그래서 내가 zope.component
를 가져올 부분에 도착하지 않으며, 그것은 ao.shorturl 네임 스페이스에 남아 있습니다. 왜?!
>>> ao.shorturl.zope.component # why?!
<module ...>
아, 고마워! 웬일인지'def __import __()'를 시도했지만'builtin .__ import__'에 할당하지 않았습니다; 바보 나. 흥미 롭 군, 난 그냥 여기에 귀하의 답변을 읽고 : http://stackoverflow.com/questions/2216828/mock-y-of-from-x-import-y-in-doctest-python/2217512#2217512 - 생각하십니까? 내 모듈의 범위에 queryUtility를 가져 오지 않으면이 상황이 더 쉬울까요? –
@Attila, 만약'zope import component'에서'component.queryUtility'를 사용했다면, 예를 들어 진짜 물건을 사용하고, 조롱 한/가짜 버전을 좀 더 쉽게 만들 수 있습니다. 다른 시간.나는 그 대답을 썼다. 나는 그것을 일반적인 것으로 추천한다. 그리고 그것은 구글에서 파이썬을 코딩하는 방식의 일부이다. (때로는 하나의 수입품 이름을 줄이기 위해 'as' 조항을 사용하기도한다.하지만 그것은' t 의미 변경). –
'from zope import component', BTW,'__import__'와 같은 함수는'name' 인자로'zope'을,'fromlist' 인자에는' 당신이'zope import from this, that, component' 등을하지 않는 한 단 하나뿐입니다 ;-); 그에 따라 트리거해야합니다. –