模拟对象不可迭代

时间:2018-12-13 18:41:08

标签: python unit-testing

我目前正在尝试(但失败)在我的简单应用程序上执行单元测试,该应用程序将数据发布到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

任何帮助都将不胜感激

4 个答案:

答案 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__以及其他双下划线魔术方法。您可以尝试使cursorconnect对象MagicMock的实例。