How to mock Python static methods and class methods
One way to do it is
def test_increment(mocker):
mocker.patch.object(Calculator, attribute='increment', return_value=10)
...actual test code...
I just did something that could be translated to your case like this:
class Calculator_Mock(object):
def __init__(self, multiplier):
... # add whatever you need here
def multiply(self, n):
... # add whatever you need here
@classmethod
def increment(self, n):
... # add whatever you need here
Then, in your test, something as simple as this:
class TestCalculator(TestCase):
def test_increment_or_whatever(self):
with patch.object(Calculator,
"increment",
return_value=Calculator_Mock.increment()) as increment_mock:
... # call whatever your calls Calculator.increment, the mock should run instead the Calculator.increment
You were patching the wrong object. You must patch the Calculator
from the Machine
class, not the general Calculator
class. Read about it here.
from mock import patch
import unittest
from calculator import Calculator
from machine import Machine
class TestMachine(unittest.TestCase):
def my_mocked_mult(self, multiplier):
return 2 * multiplier * 3
def test_bound(self):
'''The bound methods of Calculator are replaced with MockCalculator'''
machine = Machine(Calculator(3))
with patch.object(machine, "mult") as mocked_mult:
mocked_mult.side_effect = self.my_mocked_mult
self.assertEqual(machine.mult(3), 18)
self.assertEqual(machine.incr_bound(3), 5)
self.assertEqual(machine.decr_bound(3), 1)
def test_unbound(self):
'''Machine.incr_unbound() and Machine.decr_unbound() are still using
Calculator.increment() and Calculator.decrement(n), which is wrong.
'''
machine = Machine(Calculator(3))
self.assertEqual(machine.incr_unbound(3), 4) # I wish this was 5
self.assertEqual(machine.decr_unbound(3), 2) # I wish this was 1