Макет класса, импортированного в другой модуль

#python #mocking #python-mock

#питон #насмешливый #python-макет

Вопрос:

Допустим, у меня есть эти модули:

a.py

 class C:
    ...
 

b.py

 from a import C
...
def foo():
   c = C()
   ...
...
 

теперь я хочу написать тест для модуля b

test_b.py

 import unittest
import mockito

from b import foo


class TestB(unittest.TestCase):
   def test_foo():
      actual = foo()
      ...
 

Я хочу «контролировать» поведение foo() во время теста, и я хочу заменить во время test_foo() выполнения, что при C() создании внутри foo() , это не «реальный» C класс, а издевательский, с пользовательским поведением
Как я могу этого добиться?

Ответ №1:

Вы должны import b ввести его в свой test_b.py , а затем присвоить b.C вашему издевательскому классу, например:

 import unittest

import b

class TestB(unittest.TestCase):
    class MockC:
        def talk(self):
            return 'Mocked C'

    def test_foo(self):
        b.C = self.MockC
        talk = b.foo()  # returns C().talk()
        assert talk == 'Mocked C'  # ok
 

Ответ №2:

вы можете использовать unittest.mock.patch :

 import unittest.mock

from a import C
from b import foo

class MockC:
    ...

class TestB(unittest.TestCase):
   def test_foo():
        with unittest.mock.patch('a.C', new=MockC):
            actual = foo() # inside foo C will be the MockC class
            ...