我希望单元测试断言函数中的变量action
被设置为其预期值,这个变量的唯一使用时间是在调用库中传递它时。
Class Monolith(object):
def foo(self, raw_event):
action = # ... Parse Event
# Middle of function
lib.event.Event(METADATA, action)
# Continue on to use the build event.
我的想法是我可以模拟lib.event.Event
,并获取其输入参数并声明它们具有特定价值。
>这不是模拟的工作原理吗?模拟文档让我感到沮丧,因为它的不一致性,半实例以及与我想要做的事情无关的大量例子。
答案 0 :(得分:5)
您可以使用补丁装饰器然后将assert_called_with
调用到该模拟对象,如下所示:
如果你有这个结构:
example.py
tests.py
lib/__init__.py
lib/event.py
example.py
的内容是:
import lib
METADATA = 'metadata_example'
class Monolith(object):
def foo(self, raw_event):
action = 'action_example' # ... Parse Event
# Middle of function
lib.event.Event(METADATA, action)
# Continue on to use the build event.
lib/event.py
的内容是:
class Event(object):
def __init__(self, metadata, action):
pass
tests.py
的代码应该是:
import mock
import unittest
from lib.event import Event
from example import Monolith
class TestExample(unittest.TestCase):
@mock.patch('lib.event.Event')
def test_example1(self, event_mocked):
# Setup
m = Monolith()
# Exercise
m.foo('raw_event')
# Verify
event_mocked.assert_called_with('metadata_example', 'action_example')
答案 1 :(得分:2)
您也可以使用call_args
或call_args_list
。
一个简单的例子如下:
class TestExample(unittest.TestCase):
@mock.patch('lib.event.Event')
def test_example1(self, event_mocked):
args, kwargs = event_mocked.call_args
self.assertEqual(args, ['metadata_example', 'action_example'])
我只是为可能需要该示例的人快速编写了此示例-我尚未实际测试过此示例,因此可能存在一些小错误。
答案 2 :(得分:-1)
如果您想直接访问参数,该怎么办?虽然有点多余... 参见https://docs.python.org/3.6/library/unittest.mock.html#unittest.mock.call.call_list
import mock
import unittest
from lib.event import Event
from example import Monolith
class TestExample(unittest.TestCase):
@mock.patch('lib.event.Event')
def test_example1(self, event_mocked):
# Setup
m = Monolith()
# Exercise
m.foo('raw_event')
# Verify
name, args, kwargs = m.mock_calls[0]
self.assertEquals(name, "foo")
self.assertEquals(args, ['metadata_example', 'action_example'])
self.assertEquals(kwargs, {})