Как смоделировать объект, который является входом для функции? - PullRequest
0 голосов
/ 07 октября 2019

Обычно, когда я издеваюсь, у меня есть следующий тип установки

# my_script.py
import numpy as np

def my_func(x):
    out = np.power(x, 2)
    return out

, а затем для проверки вызова numpy power в my_script:

# test_myscript.py

import numpy as np
import unittest
import mock

from my_script import my_func


class TestMyScript(unittest.TestCase):

    @mock.patch("my_script.np")
    def test_my_func(self, mock_os):
        """Test that numpy.power was called"""
        a = np.array([1, 2, 3])
        my_func(a)
        mock_os.power.assert_called_with(a, 2)


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

Это отлично работает.

Но теперь, если ситуация изменится, скажем, я даю модуль numpy в качестве аргумента в my_func;Я не знаю, как в этом случае смоделировать numpy.

Как бы я смоделировал numpy в приведенной ниже функции так же, как и в test_myscript выше?

Обратите внимание, что numpy не будет импортирован в my_script.py, но вместо этого будет импортирован в отдельный скрипт, который выполняет функции из my_script.py.

# my_script.py
# numpy NOT imported in this script!

def my_func(x, numpy):
    out = numpy.power(x, 2)
    return out

РЕДАКТИРОВАТЬ:

На основе комментария @Daniel Roseman, я включаю еще немного кода, чтобы явным образом о том, как функции называются

# main_script.py

import numpy as np

from my_script import my_func

def main():
    a = np.array([1, 2, 3])
    my_func(a, np)  # numpy is passed into `my_func`

Затем, чтобы проверить, я пытаюсьниже

# test_myscript.py

import numpy as np
import unittest
import mock

from my_script import my_func

class TestMyScript(unittest.TestCase):

    @mock.patch("main_script.np")  # import from main_script since numpy is imported here
    def test_my_func(self, mock_os):
        """Test that numpy.power was called"""
        a = np.array([1, 2, 3])
        my_func(a)
        mock_os.power.assert_called_with(a, 2)


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

Но это не так с

Ran 1 test in 0.154s
>>> FAILED (failures=1)
>>> AssertionError: Expected 'power' to have been called.

1 Ответ

1 голос
/ 07 октября 2019

Я обнаружил, что использование unittest.mock.Mock объекта здесь работает лучше всего.

Итак, если у нас есть:

# my_script.py

def my_func(x, numpy):
    out = numpy.power(x, 2)
    return out

Затем, чтобы проверить его, мы имеем:

# test_myscript.py

import numpy as np
import unittest
from unittest.mock import Mock

from my_script import my_func

numpy_mock = Mock()


class TestMyScript(unittest.TestCase):

    def test_my_func(self):
        """Test that numpy.power was called"""
        a = np.array([1, 2, 3])
        _ = my_func(a, numpy_mock)  # pass the mocked object here
        numpy_mock.power.assert_called_once_with(a, 2)


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

который проходит тест

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...