Skip to content

Instantly share code, notes, and snippets.

@erdnaxeli
Created July 27, 2023 15:41
Show Gist options
  • Save erdnaxeli/f5707814c6c71b66ed70fa20f41cb1f8 to your computer and use it in GitHub Desktop.
Save erdnaxeli/f5707814c6c71b66ed70fa20f41cb1f8 to your computer and use it in GitHub Desktop.
Testing private methods vs composition
from unittest.mock import create_autospec, call
########################################
# Only one class with private methodes #
########################################
class Everything:
def do_something(self, x: int) -> int:
y = self._first_work(x)
z = self._second_work(y)
return z
def _first_work(self, x: int) -> int:
if x % 2 == 0:
return x
else:
return x - 1
def _second_work(self, x: int) -> int:
if x % 3 == 0:
return x
else:
return x - 1
class TestEverything:
def test_first_work__multiple_of_two(self):
assert Everything()._first_work(4) == 4
def test_first_work__not_multiple_of_two(self):
assert Everything()._first_work(3) == 2
def test_second_work__multiple_of_three(self):
assert Everything()._second_work(6) == 6
def test_second_work__multiple_of_three(self):
assert Everything()._second_work(5) == 4
def test_do_something__multiple_of_two__and_three(self):
assert Everything().do_something(6) == 6
def test_do_something__multiple_of_two__not_three(self):
assert Everything().do_something(4) == 3
def test_do_something__not_multiple_of_two__but_three(self):
assert Everything().do_something(7) == 6
def test_do_something__not_multiple_of_two__nor_three(self):
assert Everything().do_something(9) == 7
######################
# Use of composition #
######################
class FirstWork:
def do(self, x: int) -> int:
if x % 2 == 0:
return x
else:
return x - 1
class SecondWork:
def do(self, x: int) -> int:
if x % 3 == 0:
return x
else:
return x - 1
class WithComposition:
def __init__(self, first_work: FirstWork, second_work: SecondWork):
self.first_work = first_work
self.second_work = second_work
def do(self, x: int) -> int:
y = self.first_work.do(x)
z = self.second_work.do(y)
return z
class TestFirstWork:
def test_multiple_of_two(self):
assert FirstWork().do(4) == 4
def test_not_multiple_of_two(self):
assert FirstWork().do(3) == 2
class TestSecondWork:
def test_multiple_of_three(self):
assert SecondWork().do(6) == 6
def test_multiple_of_three(self):
assert SecondWork().do(5) == 4
class TestWithComposition:
def test_ok(self):
fw = create_autospec(FirstWork)
fw.do.return_value = 5
sw = create_autospec(SecondWork)
sw.do.return_value = 4
wc = WithComposition(fw, sw)
result = wc.do(8)
assert fw.do.call_args_list == [call(8)]
assert sw.do.call_args_list == [call(5)]
assert result == 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment