我目前正在尝试(但失败)在我的简单应用程序上执行单元测试,该应用程序将数据发布到MySQL数据库。下面是我要运行的单元测试,不确定是否可以成功测试我的代码,但是出现TypeError:'Mock'对象不可迭代
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
任何帮助都将不胜感激
答案 0 :(得分:1)
创建模拟程序时,有时必须让它知道如何响应某些可能会收到的呼叫。举个例子:
class A(object):
def __init__(self):
self.items = []
如果要创建一个模拟来代替A
的实例,则模拟将不会自动知道如何在尝试请求.items
时做出响应。您可以通过将Mock作为关键字传递给构造函数来告诉Mock特定属性的返回值,从而克服了这一问题,例如:
mocked_a = Mock(items = [])
现在,当您调用mock_a.items
时,您将得到一个空列表,因此迭代不会出错。
答案 1 :(得分:1)
要使模拟可迭代,您需要模拟其 __iter__
方法。例如:
cursor = Mock()
cursor.__iter__.return_value = []
答案 2 :(得分:1)
我花了一段时间尝试不同的东西。 MagicMock() 从来不适合我,但 Magic() 可以。谢谢!
这有效:
mocked_a = Mock(items = [])
然后,mocked_a.items 将返回 []
这对于 Mock() 不起作用,对于 MagicMock() 也不起作用。无论我如何尝试,我都无法将 [] 分配给光标!
cursor = Mock()
cursor.__iter__.return_value = []
or:
cursor = MagicMock()
cursor.__iter__.return_value = []
答案 3 :(得分:0)
错误消息TypeError: 'Mock' object is not iterable
告诉您一个模拟对象不可迭代:您正在尝试但无法对其进行迭代(for elem in ...
)或对其上调用list()
。为了使对象可迭代,需要实现__iter__
'魔术'方法(请参见https://stackoverflow.com/a/5262255/12519542)
MagicMock
对象(您在测试中导入的对象)implements __iter__
以及其他双下划线魔术方法。您可以尝试使cursor
和connect
对象MagicMock
的实例。