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)

モックを使用してこの関数をテストしようとしていますが、これをテストする方法を決めるのに苦労しています。頭に浮かぶ 2 つのオプションは、side_effectまたはを使用することassert_has_callsです。これが私がやろうとしていることの概要です。

  • func2回呼び出されるようにしたい。(終わり)
  • func呼び出しごとにモックを作成したい (未完了)
  • render が 2 回呼び出されるようにしたい。(終わり)
  • との モックが必要class_to_mockです。(まだ完成してない)email_oneemail_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に引数があることを確認するには、 からの 2 つの異なる呼び出しが必要です。class_to_mockmethod_for_class

4

1 に答える 1

2

new次の属性を使用できます@patch.object

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)
于 2016-01-13T22:30:24.727 に答える