Макет внутренних методов Python2 - PullRequest
0 голосов
/ 21 января 2020

Я новичок в издевательствах и действительно борюсь с этим. В основном в документации и на большинстве страниц SO показано, как получить макет result_value, но я хочу проверить, верны ли значения, которые я получаю из методов, а не result_value. Вот пример:

#!/usr/bin/env python

class Example:

    def one(self):
        return 1

    def two(self, one):
        print(one + 1) # basically any void method, ex: result = one + 1 and check result value if correct

    def main(self):
        self.two(self.one())

if __name__ == '__main__':
    e = Example()
    e.main()

Тест:

#!/usr/bin/env python

import unittest
import example
from mock import patch

class Example(unittest.TestCase):

    def test_one(self):
        self.assertEqual(1, et.one())

    def test_two(self):
        with patch('example.Example.two'):
            self.assertEqual(2, et.two(et.one())) # ..the part I'm stuck
                                                  # whick ofc throws AssertionError: 2 != <MagicMock name='two()' id='blablabla'>

    def test_main(self):
        # unknown part..

if __name__ == '__main__':
    et = example.Example()
    unittest.main()

Как выполнить проверку пустого метода с помощью unittest?

ОБНОВЛЕНИЕ:

так что печать Я выяснил с помощью Чепнера:

def test_twoi3(self):
        mock_print = MagicMock()
        with patch('sys.stdout', mock_print):
            print(2)
            expected = call.write('2')
            self.assertEqual(mock_print.mock_calls[0], expected)

и для main Я не совсем уверен, если это хорошее решение ...:

def test_main(self):
        with patch ('example.Example.main') as m:
            et.main(et.two(1))
        m.assert_called_with(et.two(1))

но я хочу проверять не передавая методы и значения, а если main вызывает два других метода. Как этого добиться?

Ответы [ 2 ]

0 голосов
/ 22 января 2020

Я выяснил, как проверить, были ли вызваны основные методы. Тест выглядит следующим образом:

#!/usr/bin/env python

import unittest
import example
from mock import patch, MagicMock, call

class Example(unittest.TestCase):

    def setUp(self):
        self.et = example.Example()

    def test_one(self):
        self.assertEqual(1, self.et.one())

    def test_two(self):
        mock_print = MagicMock()
        with patch('sys.stdout', mock_print):
            print(2)
            expected = call.write('2')
            self.assertEqual(mock_print.mock_calls[0], expected)

    def test_main(self):
        self.et.two = MagicMock(side_effect=self.et.two)
        self.et.one = MagicMock(side_effect=self.et.one)

        self.et.main()

        self.et.one.assert_called()
        self.et.two.assert_called()

        self.et.one.__str__ = self.et.one
        self.assertEqual(1, int(self.et.one))

if __name__ == '__main__':
    unittest.main()

После насмешливых методов из main (все они) и вызова main методов one и two были успешно вызваны. Для one вы можете вернуть значение, используя __str__

0 голосов
/ 21 января 2020

Вам не нужно ничего высмеивать (во всяком случае, напрямую); Вы хотите захватить стандартный вывод и убедиться, что это то, что вы ожидаете.

from contextlib import redirect_stdout
from io import StringIO

def test_two(self):
    stdout = StringIO()

    with redirect_stdout(stdout):
        et.two(et.one())

    self.assertEqual(stdout.getvalue(), "2\n")

Или вы можете смоделировать print и проверить, что он называется с ожидаемыми аргументами.

def test_two(self):
    with patch('__builtin__.print') as p:
        et.two(et.one())

    p.assert_called_with(2)
...