I want to mock add_new _costumer()
in class NewCoustumer
.
The filename is**: main.py**
import csv
import os
class NewCoustumer():
def __init__(self,balance_checking = 0.0 , balance_saving = 0.0):
self.balance_checking = balance_checking
self.balance_saving = balance_saving
if not os.path.exists("bank_data.csv") or os.stat("bank_data.csv").st_size == 0:
with open("bank_data.csv", "w", newline="")as file:
writer = csv.writer(file)
writer.writerow(["account_id","first_name","last_name","password","balance_checking","balance_saving"])
def generate_account_id(self):
try:
with open("bank_data.csv", "r")as file:
reader = csv.reader(file)
data = [row for row in reader if row and row[0].isdigit()]
if len(data) > 1:
last_id = int(data[-1][0])
return str(last_id + 1)
else:
return "10001"
except FileNotFoundError:
return "10001"
def add_new_customer(self):
account_id = self.generate_account_id()
first_name = input("Enter first name: ")
last_name = input("Enter last name: ")
password = input("Enter password: ")
balance_checking = self.balance_checking
balance_saving = self.balance_saving
with open("bank_data.csv", mode='a', newline='') as file:
writer = csv.writer(file)
writer.writerow([account_id, first_name, last_name, password,balance_checking,balance_saving])
return True
import unittest
from unittest.mock import patch, Mock
from main import NewCoustumer
class AddCustomer(unittest.TestCase, NewCoustumer):
user_input = ['dan', 'sam','dan123']
@patch('builtins.input', side_effect=[user_input])
def test_add(self, mock_inputs):
result = self.add_new_customer()
self.assertTrue(result,True)
if __name__ == '__main__':
unittest.main(verbosity=2 )
it shows this error :
(File "C:\Python313\Lib\unittest\mock.py", line 1171, in _mock_call
return self._execute_mock_call(*args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "C:\Python313\Lib\unittest\mock.py", line 1228, in _execute_mock_call
result = next(effect)
StopIteration)
The error is because your side_effect
in the patch
decorator is expecting 3 input calls, but you're providing a single list. Therefore, the mock tries to iterate through that list three times. When it reaches the end of the list, it tries to get the next element and throws the error.
The correct code
import unittest
from unittest.mock import patch, Mock
from main import NewCoustumer
class TestAddCustomer(unittest.TestCase):
def test_add(self):
user_inputs = ['dan', 'sam', 'dan123']
with patch('builtins.input', side_effect=user_inputs):
customer = NewCoustumer() # create an instance of NewCoustumer
result = customer.add_new_customer()
self.assertTrue(result)
if __name__ == '__main__':
unittest.main(verbosity=2)
In your code AddCustomer
are inheriting from both unittest.TestCase
and NewCoustumer
. The class now only inherits from unittest.TestCase
and an instance of NewCoustumer
is created inside the test method.