(Python 2.6)
我在MagicMock补丁中遗漏了一些内容
给出以下生产代码:
class MyQueue(object):
def send(self, message):
pass
class MessageSender(object):
def send_all(self, messages):
queue = MyQueue()
for message in messages:
queue.send(message)
我有以下测试:
class MessageSenderTest(TestCase):
@patch('path.to.MyQueue')
def test_can_send_all_messages(self, queue):
messages = ['foo', 'bar', 'baz']
sender = MessageSender()
sender.send_all(messages)
queue.send.assert_has_calls([call(message) for message in messages])
这给了我:
AssertionError: Calls not found.
Expected: [call('foo'), call('bar'), call('baz')]
Actual: []
我认为sender
产生的模拟会让我做出断言。
答案 0 :(得分:2)
请注意,您没有在测试方法中使用已修补的queue
实例,因为它是由MessageSender
类实例化的。这导致每次调用MyQueue
方法时都会实例化模拟的send
。实际上,您可以稍微修改一下断言并获取以下调用列表:
expected = [call()] + [call().send(message) for message in messages]
self.assertEquals(queue.mock_calls, expected)
在这种形式下,测试通过。但是,我认为MessageSender
类在其构造函数方法中接收MyQueue
会更自然,因此可以在测试中模拟它。请参阅此替代实施:
# file: main.py
class MyQueue(object):
def send(self, message):
pass
class MessageSender(object):
def __init__(self, queue):
self.queue = queue
def send_all(self, messages):
for message in messages:
self.queue.send(message)
使用它,测试读起来更自然:
# file: test.py
import unittest
from mock import patch, call
import main
class MessageSenderTest(unittest.TestCase):
@patch('main.MyQueue')
def test_can_send_all_messages(self, queue):
messages = ['foo', 'bar', 'baz']
sender = main.MessageSender(queue) # <-- here is where you do use `queue`
sender.send_all(messages)
queue.send.assert_has_calls([call.send(message) for message in messages])
if __name__ == '__main__':
unittest.main()