[英]Python: Mock Patch module that's used in an array
Here is my method: 这是我的方法:
def _eda_workflow(self, workflow_id, account_id):
uuids = [str(uuid.uuid4()) for x in range(2)]
return {
'id': workflow_id,
'root': uuids[0],
'accountId': account_id,
'steps': [
{
'this': uuids[0],
'next': [uuids[1]],
'type': 'on-contact-signed-up',
'displayName': 'Sign Up',
'constraints': {},
},
{
'this': uuids[1],
'prev': uuids[0],
'next': [],
'type': 'on-time-elapsed',
'displayName': 'Send the email after delay or not!',
'delay': 'PT0M',
'sideEffect': {
'task': 'sendEmail',
'constraints': {},
'mailing_data': {},
'email': {}
}
}
]
}
The problem I am having is when I write this 我遇到的问题是写这篇文章时
def generate_uuids():
return ["10e6e848-dc77-4057-890e-5acd4ed9aeb3", "d8d501a7-f7e7-4423-921c-e0f39b7e1301"]
@mock.patch('path.to.uuid')
def test_translte_workflow(self, uuid_mock):
uuid_mock.uuid4.side_effect = generate_uuids
The return method is returning a list
of values instead of what I am expecting. return方法返回值list
,而不是我期望的值。 Not sure how to write this test correctly 不确定如何正确编写此测试
Side effect is just for specifying something additional to happen whenever the mock is called. 副作用只是用于指定每次调用模拟时都会发生的其他事情。 I think this is more what you were looking for: 我认为这更是您想要的:
def fake_uuid4():
yield "10e6e848-dc77-4057-890e-5acd4ed9aeb3"
yield "d8d501a7-f7e7-4423-921c-e0f39b7e1301"
@mock.patch('path.to.uuid.uuid4', fake_uuid4().next)
def test_translte_workflow(self):
...
Your generate_uuids
function is returning a list of UUIDs, so that's what you get. 您的generate_uuids
函数将返回UUID 列表 ,这就是您得到的。
If you want to create a function that returns one UUID at a time, from a pool of exactly two UUIDs, create an iterator from a list of two UUIDs and return iterator.next()
from that function. 如果要创建一次从正好两个 UUID的池中一次返回一个UUID的函数,请从两个 UUID的列表中创建一个迭代器 ,然后从该函数返回iterator.next()
。 If you also want to make assertions on those UUIDs, store them separately from the iterator: 如果您还想对这些UUID进行断言,请将其与迭代器分开存储:
import mock
import unittest
import uuid
TEST_UUIDS = ["10e6e848-dc77-4057-890e-5acd4ed9aeb3",
"d8d501a7-f7e7-4423-921c-e0f39b7e1301"]
uuid_pool = iter(TEST_UUIDS)
def generate_uuid():
return uuid_pool.next()
def func():
uuid_1 = uuid.uuid4()
uuid_2 = uuid.uuid4()
return [uuid_1, uuid_2]
class TestUUIDs(unittest.TestCase):
@mock.patch('uuid.uuid4', generate_uuid)
def test_uuid_mock(self):
actual = func()
expected = TEST_UUIDS
self.assertEquals(expected, actual)
unittest.main()
Once you exhaust that iterator (after fetching two elements), it will raise StopIteration
. 一旦耗尽了该迭代器(在获取两个元素之后),它将引发StopIteration
。
If you want to create a function that always returns just one an UUID from an endless stream of UUIDs, you can use itertools.cycle
: 如果要创建一个函数,该函数总是从无穷无尽的UUID流中仅返回一个UUID,则可以使用itertools.cycle
:
from itertools import cycle
uuid_pool = cycle(["10e6e848-dc77-4057-890e-5acd4ed9aeb3",
"d8d501a7-f7e7-4423-921c-e0f39b7e1301"])
I needed to solve something similar and, after some experimenting, preferred using an iterable with @patch
and side_effect
. 我需要解决类似的问题,并且在进行了一些实验之后,更喜欢使用带有@patch
和side_effect
的迭代side_effect
。 In my case, instead of populating an array, I was populating the return value of a function called a layer deeper than the function in my test. 就我而言,不是填充数组,而是填充了比测试中的函数更深的称为函数层的函数的返回值。
TEST_UUIDS = ["10e6e848-dc77-4057-890e-5acd4ed9aeb3",
"d8d501a7-f7e7-4423-921c-e0f39b7e1301"]
TEST_UUID_POOL = iter(TEST_UUIDS)
@patch('path.to.function1', side_effect=TEST_UUID_POOL)
def test_translate_workflow(self, uuid_mock):
# function 1 is called twice in function2
function2()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.