Peter, I'm so sorry, the letter was originally wrote to Terry, not to you! I guess Terry not very familar to unit testing because he said:
-- cut -- I am not familiar with pmock, but my impression is that mock objects are for objects that you may not have available, such as a connection to a database or file or instance of an umimplemented class ;-). For such objects, the mock-ness consists in returning canned rather than actual fetched or calculated answers. Iterators, on the other hand, are almost as -- end -- and i just want to say, mocking object is a useful testing method , not was telling a tutorial. :-) What you said about the overuse of the generic mock object is very interesting. I did not think that before. I believe that use generic or customized mocks is a problem of balance, so we may call it Art :-) Below is my code, you may look it to understand my original question (sorry for the coding for i am totally a python newbie): --------------------------------------- import unittest from pmock import * from mainctr import MainCtr class MainCtrTest(unittest.TestCase): def testProcess(self): filePicker = MockFilePicker() filePicker.expectedNextCalls = len(MockFilePicker.fns) + 1 rpt0 = "foo" rpt1 = "bar" (router0, router1) = (Mock(), Mock()) router0.expects(once()).feedIn(eq(MockFilePicker.fns)) router1.expects(once()).feedIn(eq(MockFilePicker.fns)) router0.expects(once()).deliver() router1.expects(once()).deliver() router0.expects(once()).getDeliveredSrcList().will(return_value(["fn0", "fn2"])) router1.expects(once()).getDeliveredSrcList().will(return_value([])) router0.expects(once()).getDeliveryRpt().will(return_value(rpt0)) router1.expects(once()).getDeliveryRpt().will(return_value(rpt1)) routes = [router0, router1] ctr = MainCtr(filePicker, routes) ctr.process() self.assertEquals(ctr.getProcessRpt(), [rpt0, rpt1]) filePicker.verify() router0.verify() router1.verify() class MockFilePicker: fns = ["f0", "f1", "f2"] idx = 0 nextCalls = 0 resetCalls = 0 expectedResetCalls = 1 expectedNextCalls = 0 processedSet = set() expectedProcessedSet = set(["fn0", "fn2"]) rememberProcessedCalls = 0 expectedRememberProcessedCalls = 1 def __iter__(self): return self def reset(self): self.resetCalls += 1 def next(self): self.nextCalls += 1 if self.idx < len(self.fns): self.idx += 1 return self.fns[self.idx - 1] else: raise StopIteration def processed(self, fn): self.processedSet.add(fn) def rememberProcessed(self): self.rememberProcessedCalls += 1 def verify(self): if self.nextCalls != self.expectedNextCalls: raise Exception("nextCalls: " + str(self.nextCalls)) if self.resetCalls != self.expectedResetCalls: raise Exception("resetCalls: " + str(self.resetCalls)) if self.processedSet != self.expectedProcessedSet: raise Exception("processedSet: " + str(self.processedSet)) if self.rememberProcessedCalls != self.expectedRememberProcessedCalls: raise Exception("rememberProcessedCalls: " + str(self.rememberProcessedCalls)) if __name__ == "__main__": unittest.main() -- http://mail.python.org/mailman/listinfo/python-list