I am currently trying (and failing) to perform unit tests on my simple app which posts data to a MySQL database. Below is the unit test I am trying to run, not sure if this will eve test my code successfully, but is coming up with a TypeError: 'Mock' object is not iterable
Unit_Test.py
from unittest import mock
from unittest.mock import patch, MagicMock
from unittest.mock import Mock
from source.src.scores import *
@mock.patch('source.src.scores.request')
def test_add_scores(self):
columns = ["Match_ID", "Home_Score", "Away_Score"]
values = [1, 1, 1]
expected_score = {columns[i]: values[i] for i in range(len(columns))}
with patch('source.src.scores.mysql.connector') as patch_connector:
cursor = Mock()
cursor.fetchone.return_value = values
cursor.column_names = columns
connect = Mock()
connect.cursor.return_value = cursor
patch_connector.connect.return_value = connect
with patch('source.src.scores.jsonify') as json:
json.return_value = expected_score
json_return, http_code = add_score()
assert patch_connector.connect.called
assert connect.cursor.called
assert connect.commit.called
assert cursor.fetchone.called
self.assertEqual(cursor.execute.call_count, 2)
self.assertDictEqual(expected_score, json_return)
if __name__ == '__main__':
test_add_scores()
scores.py
def execute_query(cursor, qry):
print("Executing query...")
cursor.execute(qry)
def execute_query_json(cursor, qry, cnx):
print("Executing JSON query...")
cursor.execute(qry, (request.json['Match_ID'],
request.json['Home_Score'],
request.json['Away_Score'],
)
)
cnx.commit()
def add_score():
cnx = conn_db()
cursor = cnx.cursor()
print("Updating score")
execute_query_json(cursor, "INSERT INTO scores (Match_ID, Home_Score, Away_Score) VALUES (%s,%s,%s)", cnx)
execute_query(cursor, "SELECT * FROM scores WHERE Score_ID=" + str(cursor.lastrowid))
recs = extract_records(cursor)
return jsonify({'discipline':recs}), 201
Any helps is greatly appreciated
When you create a mock, you sometimes have to let it know how to respond to some of the calls that will be expected of it. Take, for example:
class A(object):
def __init__(self):
self.items = []
If you were to create a Mock to use in place of an instance of A
, the mock wouldn't automagically know how to respond if you attempt to request .items
. You can overcome this by telling the Mock what to return for a particular property by passing that as a keyword to the constructor, like so:
mocked_a = Mock(items = [])
Now, when you call mock_a.items
you'll get an empty list, so iteration won't fault.
To make mock iterable you need to mock its __iter__
method. For example:
cursor = Mock()
cursor.__iter__.return_value = []
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With