python - How do I patch a class in the same file as a class under test, that is initialized before the test begins? -


(nota bene: heavily modified original question, include details erroneously elided.)

this (summarized) file (common.py) i'm testing. contains decorator (derived decorum library) calls class method on object(a): want patch out a, because code makes external call i'm not testing.

from decorum import decorum   class a:     @classmethod     def c(cls):         pass   class classydecorum(decorum):     """hack allow decorated instance methods of class object run decorators.     replace once decorum 1.0.4+ comes out.     """      def __get__(self, instance, owner):         functools import partial         return partial(self.call, instance)   class b(decorum):      def __init__(self, *args, **kwargs):         super().__init__(*args, **kwargs)      def init(self, *args, **kwargs):         a.c()         return super().init(*args, **kwargs) 

i'd @patch class a in unittest, isolate , check b.d()'s functionality. unittest (located in test/test_common.py):

class bdecoratedclass(magicmock):      @b     def dummy_func(self):         return "success"  class testb(testcase):     @patch('unittest_experiment.a', autospec=true)     def test_d(self, mock_a):         b = bdecoratedclass()         b.dummy_func()         mock_a.c.assert_called_once_with()  # fails 

debugging above, see a never mocked: code proceeds a's code, makes sense mock_a never called, , assertion fails. however, i'd monkey patch a. approach works if i'm monkey patching import exists in common.py, apparently not if class defined there?

note think issue of where i'm patching, @patch('common.a', autospec=true) should more @patch('where.python.actually.finds.a.when.b.calls.a', autospec=true). i'm unclear on how determine if case, , if so, correct path is. instance, @patch('bdecorated.common.a', autospec=true) not work.

thanks @user2357112, arrived @ solution. caveat: don't know if standard or 'best' practice, seems work.

first, move bdecoratedclass it's own file in test/dummy.py. change test this:

class testb(testcase):     @patch('common.a', autospec=true)     def test_d(self, mock_a):         test.dummy import bdecoratedclass          b = bdecoratedclass()         b.dummy_func()         mock_a.c.assert_called_once_with()  # succeeds 

this forces patch execute prior import of dummy class being decorated. it's little weird because import inside function, test seems fine.

bigger caveat:

this works first test imports module where, in case bdecoratedclass imports from. @ juncture else in class has been loaded , cannot patched.


Comments

Popular posts from this blog

c# - Update a combobox from a presenter (MVP) -

How to understand 2 main() functions after using uftrace to profile the C++ program? -

How to put a lock and transaction on table using spring 4 or above using jdbcTemplate and annotations like @Transactional? -