I'm new to unit testing. I'm working on an ATM program. I want to make a unit test for the deposit operation. I have checked online but i am not getting an answer to my problem. This is my first time of posting here. Thank you for the assistance in advance
This is my code below
def deposit_operation(user):
amount_to_deposit = int(input('ENTER AMOUNT YOU WANT TO DEPOSIT: ')
# amount should be in multiples of 1,000
if amount_to_deposit % 1000 != 0:
print('AMOUNT YOU WANT TO DEPOSIT MUST BE IN MULTIPLES OF 1000 NAIRA NOTES')
deposit_operation(user)
else:
user[4] = user[4] amount_to_deposit
print(f'*** YOUR NEW BALANCE IS: {user[4]} NAIRA ****')
perform_another_operation(user)
CodePudding user response:
You separate out the parts that do I/O like take user input from the parts that do operations on the input.
def get_user_input():
user_input = input("Enter the amount to deposit: ")
data = validate_user_input(user_input)
if data:
return data
else:
print("Input must be a number that is a multiple of 1000")
return get_user_input()
def validate_user_input(value):
try:
parsed = int(user_input)
if parsed % 1000 == 0:
return parsed
else:
return False
except:
return False
def update_account(user, amount):
user[4] = user[4] amount
return user
if __name__ == "__main__":
user = ...
update_account(user, get_user_input())
Now you can test the validation logic and the account update logic independently and you don't need to test get_user_input
at all. No complicated mocking, just good decomposition.
from unittest import TestCase
class TestAtm(TestCase):
def test_validate_user_input(self):
assert(validate_user_input("1") is False)
assert(validate_user_input("1000") is True)
assert(validate_user_input("pizza") is False)
# and so on...
def test_update_amount(self):
# Test that acct gets updated
Also, please don't use lists to store positional data like that. Use a dictionary or a namedtuple or a dataclass or an actual user class. Trying to remember that the 5th index is the account value is asking for bugs.
CodePudding user response:
Something like:
test_deposit_operation.py
import mock
from unittest import TestCase
import builtins
# define user equal to [1,2,3,4,5]
def deposit_operation(user=[1,2,3,4,5]):
amount_to_deposit = int(input('ENTER AMOUNT YOU WANT TO DEPOSIT: '))
# amount should be in multiples of 1,000
if amount_to_deposit % 1000 != 0:
return('AMOUNT YOU WANT TO DEPOSIT MUST BE IN MULTIPLES OF 1000 NAIRA NOTES')
else:
user[4] = user[4] amount_to_deposit
return(f'*** YOUR NEW BALANCE IS: {user[4]} NAIRA **** ')
#perform_another_operation(user)
class Test(TestCase):
def test_deposit_operation_divide_by_1000_not_equel_zero(self):
with mock.patch.object(builtins, 'input', lambda _: 10001):
self.assertEqual(deposit_operation(), 'AMOUNT YOU WANT TO DEPOSIT MUST BE IN MULTIPLES OF 1000 NAIRA NOTES')
def test_deposit_operation_divide_by_1000_equel_zero(self ):
with mock.patch.object(builtins, 'input', lambda _: 1000):
self.assertEqual(deposit_operation(), '*** YOUR NEW BALANCE IS: 1005 NAIRA **** ')
then:
pytest test_deposit_operation.py