Using python mock to count the number of method calls

I am just starting to use the python mocking framework. I would just like to count the number of times a method is called, without removing the effects of the actual method call.

For example, in this simple counter example, I would like both to increment the counter and the track that it called:

import unittest import mock class Counter(object): def __init__(self): self.count = 0 def increment(self): self.count += 1 class CounterTest(unittest.TestCase): def test_increment(self): c = Counter() c.increment() self.assertEquals(1, c.count) def test_call_count(self): with mock.patch.object(Counter, 'increment') as fake_increment: c = Counter() self.assertEquals(0, fake_increment.call_count) c.increment() self.assertEquals(1, fake_increment.call_count) # increment() didn't actually get called. self.assertEquals(1, c.count) # Fails. if __name__ == '__main__': unittest.main() 

Is it possible to force mock call the mocked method after registering the call, or simply mean that I want to preserve the effect of the phase function?

+6
source share
2 answers

Just use wrappers:

 c = Counter() with mock.patch.object(Counter, 'increment', wraps=c.increment) as fake_increment: 

There might be some binding problems if you initialize c later, since the function passed to wraps will not know about self .

+5
source

I am not a super experience in mock 1 but I executed it using the shell functions, and not the default MagicMock :

 class FuncWrapper(object): def __init__(self, func): self.call_count = 0 self.func = func def __call__(self, *args, **kwargs): self.call_count += 1 return self.func(*args, **kwargs) class CounterTest(unittest.TestCase): def test_call_count(self): c = Counter() new_call = FuncWrapper(c.increment) with mock.patch.object(c, 'increment', new=new_call) as fake_increment: print fake_increment self.assertEquals(0, fake_increment.call_count) c.increment() self.assertEquals(1, fake_increment.call_count) self.assertEquals(1, c.count) # Fails. 

Of course, this FuncWrapper pretty minimal. It just counts the calls and then passes the flow control back to the original function. If you need to test other things at the same time, you need to add FuncWrapper to the class. I also just fixed the class instance, not the whole class. The main reason for this is because I need an instance method in FuncWrapper .

1 Actually, I just started to study - think about yourself, -).

+2
source

All Articles