[TIP] Struggling with pymock
Rod Hyde
rod.hyde at gmail.com
Tue Sep 18 23:53:54 PDT 2007
Having decided to give pymock a try, I've run into a problem with
expectAndRaise(). My tests that use it keep failing with
RecordedCallsWereNotReplayedCorrectly and I'm beginning to wonder if
I'm doing something fundamentally wrong.
For example, I have a piece of code that attempts to make an FTP
connection to a server and retries if it isn't available. I wanted to
test the fact that it retries, so I wrote a test that uses
expectAndRaise().
Here's the test. The idea is that the connection isn't available on
the first attempt, but is available on the second attempt.
def test_do_work_retries_when_connection_down():
HOST = 'host at somewhere.com'
USER = 'user'
PASSWORD = 'password'
worker = ProblemWorker(HOST, USER, PASSWORD)
controller = pymock.Controller()
worker.make_ftp = controller.mock()
controller.expectAndRaise(worker.make_ftp(HOST, USER, PASSWORD),
socket.error(10060, 'timed out'))
conn = controller.mock()
controller.expectAndReturn(worker.make_ftp(HOST, USER, PASSWORD),
conn)
conn.set_pasv(True)
conn.quit()
controller.replay()
worker.do_work()
controller.verify()
And here's the cut-down piece of code that it is testing...
class ProblemWorker(object):
def __init__(self, host, user, password):
self.host = host
self.user = user
self.password = password
self.make_ftp = ftplib.FTP
def make_connection(self):
while True:
try:
conn = self.make_ftp(self.host, self.user, self.password)
conn.set_pasv(True)
return conn
except socket.error, e:
if e.args[0] not in (10060, 10061):
raise
# sleep(60)
def do_work(self):
conn = self.make_connection()
# Do something useful here.
conn.quit()
When I run the test, it fails as follows...
C:>nosetests test\test_hack_ftp.py
E
======================================================================
ERROR: test_hack_ftp.test_do_work_retries_when_connection_down
----------------------------------------------------------------------
Traceback (most recent call last):
File "c:\python25\lib\site-packages\nose-0.10.0b1-py2.5.egg\nose\case.py", lin
e 177, in runTest
self.test(*self.arg)
File "B:\python\WBI\StopWBI\test\test_hack_ftp.py", line 25, in test_do_work_r
etries_when_connection_down
worker.do_work()
File "B:\python\WBI\StopWBI\hack_ftp.py", line 24, in do_work
conn = self.make_connection()
File "B:\python\WBI\StopWBI\hack_ftp.py", line 15, in make_connection
conn = self.make_ftp(self.host, self.user, self.password)
File "c:\python25\lib\site-packages\pymock\pymock.py", line 263, in __call__
return self.__controller.recordOrPlayback(functionCall)
File "c:\python25\lib\site-packages\pymock\pymock.py", line 137, in recordOrPl
ayback
return self.playback(action)
File "c:\python25\lib\site-packages\pymock\pymock.py", line 149, in playback
exprValue = recordedAction.playback()
File "c:\python25\lib\site-packages\pymock\pymock.py", line 408, in playback
super(FunctionCallAction, self).playback()
File "c:\python25\lib\site-packages\pymock\pymock.py", line 328, in playback
self.playbackPolicy.playback()
File "c:\python25\lib\site-packages\pymock\pymock.py", line 484, in playback
raise RecordedCallsWereNotReplayedCorrectly()
RecordedCallsWereNotReplayedCorrectly
----------------------------------------------------------------------
Ran 1 test in 0.010s
FAILED (errors=1)
All my other test code which doesn't use expectAndRaise() works just
fine. Am I doing something fundamentally wrong here?
--- Rod
More information about the testing-in-python
mailing list