2016-01-13 111 views
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_effectassert_has_calls。以下是我试图做的事情。

  • 我想确保func被调用两次。 (完成)
  • 我希望为每个func调用的模拟(未完成)
  • 我想,以确保呈现被调用了两次。 (完成)
  • 我想确保class_to_mock调用与email_one 这是我需要email_oneemail_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_mockmethod_for_class中有参数。

回答

1

可以在@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)