mock
salary.py
import requests
class ThirdPartyBonusRestApi(object):
def get_api_name(self):
return 'Bonus!'
def bonus_price(self, year):
r = requests.get('http://localhost/bonus', params={'year':year})
return r.json()['price']
class Salary(object):
def __init__(self, base=100, year=2017):
self.bonus_api = ThirdPartyBonusRestApi()
self.base = base
self.year = year
def get_from_boss(self):
return 0
def calculation_salary(self):
bonus = 0
if self.year < 2020:
try:
bonus = self.bonus_api.bonus_price(year=self.year)
except ConnectionRefusedError:
bonus = 0
bonus += self.get_from_boss()
return self.base + bonus
test_salary.py
import unittest
from unittest.mock import MagicMock
from unittest import mock
import salary
class TestSalary(unittest.TestCase):
def test_calculation_salary(self):
s = salary.Salary(year=2017)
s.bonus_api.bonus_price = MagicMock(return_value=1)
self.assertEqual(s.calculation_salary(), 101)
s.bonus_api.bonus_price.assert_called()
s.bonus_api.bonus_price.assert_called_once()
s.bonus_api.bonus_price.assert_called_with(year=2017)
s.bonus_api.bonus_price.assert_called_once_with(
year=2017
)
self.assertEqual(s.bonus_api.bonus_price.call_count, 1)
def test_calculation_salary_no_salary(self):
s = salary.Salary(year=2050)
s.bonus_api.bonus_price = MagicMock(return_value=0)
self.assertEqual(s.calculation_salary(), 100)
s.bonus_api.bonus_price.assert_not_called()
@mock.patch('salary.ThirdPartyBonusRestApi.bonus_price', return_value=1)
def test_calculation_salary_patch(self, mock_bonus):
#mock_bonus.return_value = 1
s = salary.Salary(year=2017)
#salary_price = s.calculation_salary()
#s.bonus_api.bonus_price = MagicMock(return_value=1)
self.assertEqual(s.calculation_salary(), 101)
mock_bonus.assert_called()
def test_calculation_salary_patch_with(self):
with mock.patch('salary.ThirdPartyBonusRestApi.bonus_price') as mock_bonus:
mock_bonus.return_value = 1
s = salary.Salary(year=2017)
# salary_price = s.calculation_salary()
# s.bonus_api.bonus_price = MagicMock(return_value=1)
self.assertEqual(s.calculation_salary(), 101)
mock_bonus.assert_called()
def setUp(self):
self.patcher = mock.patch('salary.ThirdPartyBonusRestApi.bonus_price')
self.mock_bonus = self.patcher.start()
def tearDown(self):
self.patcher.stop()
def test_calculation_salary_patch_patcher(self):
#Not required because there is setup
#patcher = mock.patch('salary.ThirdPartyBonusRestApi.bonus_price')
#mock_bonus = patcher.start()
self.mock_bonus.return_value = 1
s = salary.Salary(year=2017)
salary_price = s.calculation_salary()
# s.bonus_api.bonus_price = MagicMock(return_value=1)
self.assertEqual(salary_price, 101)
self.mock_bonus.assert_called()
#Not needed because there is tearDown
#patcher.stop()
def test_calculation_salary_patch_side_effect(self):
#def f(year):
# return 1
#self.mock_bonus.side_effect = f
#self.mock_bonus.side_effect = lambda year: 1
#self.mock_bonus.side_effect = ConnectionRefusedError
self.mock_bonus.side_effect = [1,2,3,ValueError('Bankrupt!!!')]
s = salary.Salary(year=2017)
salary_price = s.calculation_salary()
self.assertEqual(salary_price, 101)
s = salary.Salary(year=2018)
salary_price = s.calculation_salary()
self.assertEqual(salary_price, 102)
s = salary.Salary(year=2019)
salary_price = s.calculation_salary()
self.assertEqual(salary_price, 103)
s = salary.Salary(year=200)
with self.assertRaises(ValueError):
s.calculation_salary()
@mock.patch('salary.ThirdPartyBonusRestApi', spec=True)
@mock.patch('salary.Salary.get_from_boss')
def test_calculation_salary_class(self, mock_boss, MockRest):
mock_boss.return_value = 10
mock_rest = MockRest.return_value
#mock_rest = MockRest()
mock_rest.bonus_price.return_value = 1
mock_rest.get_api_name.return_value = 'Money'
s = salary.Salary(year=2017)
salary_price = s.calculation_salary()
self.assertEqual(salary_price, 111)
mock_rest.bonus_price.assert_called()