模拟使用不同参数调用两次的函数
Mocking a function that is invoked twice with different arguments
假设我有以下功能:
def function_to_test(context):
list_of_invocations = [ func('arg%s' % number) for number in [1,2]]
email_one = list_of_invocations[0].render(context)
email_two = list_of_invocations[1].render(context)
instance = class_to_mock(email_one, arg_1, arg_2)
instance.method_for_class(email_two, 'text/html')
instance.send()
@mock.patch('app.foo.class_to_mock')
@mock.patch('app.foo.func')
def test_render_and_send_email(self, func_mock, mock_to_class):
render_method = mock.Mock()
render_method.return_value = mock.Mock()
class_method = mock.Mock()
class_method.return_value = mock.Mock()
func_mock.return_value = mock.MagicMock(render=render_method)
mock_to_class.return_value = mock.Magic(method_for_class=class_method)
function_to_test('context goes heres')
self.assertEqual(func_mock.call_count, 2)
self.assertEqual(render_method.call_count, 2)
self.assertEqual(mock_to_class.call_count, 1)
self.assertEqual(method_class.call_count,1)
我正在尝试使用模拟测试此功能,但我无法决定如何测试它。想到的两个选项是使用 side_effect
或 assert_has_calls
。这是我正在尝试做的事情的运行。
- 我想确保
func
被调用了两次。 (完成)
- 我想为每个
func
调用创建一个模拟 (未完成)
- 我想确保 render 被调用了两次。 (完成)
- 我想确保用
email_one
调用 class_to_mock
这是我需要 email_one
和 email_two
的模拟。 (未完成)
测试会是这样的
`mock_to_class.assert_called_once_with(*MOCK EMAIL ONE*,'one', 'two')`
我想要 '''method_for_class''' 看起来像这样的东西 (未完成):
class_method.assert_called_once_with(*MOCK EMAIL TWO*, 'text/html')
希望这是有道理的。基本上,我需要来自 func
的两个不同的调用来确保 class_to_mock
和 method_for_class
.
中有参数
您可以在 @patch.object
中使用 new
属性:
email_one=Mock()
email_two=Mock()
func_call_count = 0
def my_func_mock():
global func_call_count
func_call_count += 1
if func_call_count == 1:
do_invocation_1()
if func_call_count == 2:
do_invocation_2()
def do_invocation_1():
return [email_one, email_two]
def do_invocation_2():
return [email_one, email_two]
@mock.patch('app.foo.class_to_mock')
@mock.patch('app.foo.func', new=my_func_mock)
def test_render_and_send_email(self, func_mock, mock_to_class):
render_method = mock.Mock()
render_method.return_value = mock.Mock()
class_method = mock.Mock()
class_method.return_value = mock.Mock()
func_mock.return_value = mock.MagicMock(render=render_method)
mock_to_class.return_value = mock.Magic(method_for_class=class_method)
function_to_test('context goes heres')
self.assertEqual(func_call_count, 2) # Use the func_call_count instead
self.assertEqual(render_method.call_count, 2)
mock_to_class.assert_called_once_With(email_one, email_two) # Now you can assert it is called once with email_one & two
self.assertEqual(method_class.call_count,1)
假设我有以下功能:
def function_to_test(context):
list_of_invocations = [ func('arg%s' % number) for number in [1,2]]
email_one = list_of_invocations[0].render(context)
email_two = list_of_invocations[1].render(context)
instance = class_to_mock(email_one, arg_1, arg_2)
instance.method_for_class(email_two, 'text/html')
instance.send()
@mock.patch('app.foo.class_to_mock')
@mock.patch('app.foo.func')
def test_render_and_send_email(self, func_mock, mock_to_class):
render_method = mock.Mock()
render_method.return_value = mock.Mock()
class_method = mock.Mock()
class_method.return_value = mock.Mock()
func_mock.return_value = mock.MagicMock(render=render_method)
mock_to_class.return_value = mock.Magic(method_for_class=class_method)
function_to_test('context goes heres')
self.assertEqual(func_mock.call_count, 2)
self.assertEqual(render_method.call_count, 2)
self.assertEqual(mock_to_class.call_count, 1)
self.assertEqual(method_class.call_count,1)
我正在尝试使用模拟测试此功能,但我无法决定如何测试它。想到的两个选项是使用 side_effect
或 assert_has_calls
。这是我正在尝试做的事情的运行。
- 我想确保
func
被调用了两次。 (完成) - 我想为每个
func
调用创建一个模拟 (未完成) - 我想确保 render 被调用了两次。 (完成)
- 我想确保用
email_one
调用class_to_mock
这是我需要email_one
和email_two
的模拟。 (未完成)
测试会是这样的
`mock_to_class.assert_called_once_with(*MOCK EMAIL ONE*,'one', 'two')`
我想要 '''method_for_class''' 看起来像这样的东西 (未完成):
class_method.assert_called_once_with(*MOCK EMAIL TWO*, 'text/html')
希望这是有道理的。基本上,我需要来自 func
的两个不同的调用来确保 class_to_mock
和 method_for_class
.
您可以在 @patch.object
中使用 new
属性:
email_one=Mock()
email_two=Mock()
func_call_count = 0
def my_func_mock():
global func_call_count
func_call_count += 1
if func_call_count == 1:
do_invocation_1()
if func_call_count == 2:
do_invocation_2()
def do_invocation_1():
return [email_one, email_two]
def do_invocation_2():
return [email_one, email_two]
@mock.patch('app.foo.class_to_mock')
@mock.patch('app.foo.func', new=my_func_mock)
def test_render_and_send_email(self, func_mock, mock_to_class):
render_method = mock.Mock()
render_method.return_value = mock.Mock()
class_method = mock.Mock()
class_method.return_value = mock.Mock()
func_mock.return_value = mock.MagicMock(render=render_method)
mock_to_class.return_value = mock.Magic(method_for_class=class_method)
function_to_test('context goes heres')
self.assertEqual(func_call_count, 2) # Use the func_call_count instead
self.assertEqual(render_method.call_count, 2)
mock_to_class.assert_called_once_With(email_one, email_two) # Now you can assert it is called once with email_one & two
self.assertEqual(method_class.call_count,1)