Mock class not being injected when running all django-nose tests together
Asked Answered
B

0

8

I'm running into a strange problem that seems to come about from how python unit tests manage their imports and how this relates to the mock package. This is for a django project, using django-nose/nose for unit test running and mock for mocking.

I have a unit test using mock which works perfectly fine when run alone (python manage.py test tests/test_code.py)

inside test_code.py:

from my.app.models.bookstore import create_from_proxy

class MockTestCase( TestCase ):

    def setUp( self ):
        self.patcher = patch( 'my.app.models.bookstore.BookProxy', autospec=True )
        self.mock_proxy = self.patcher.start()
        self.proxy_instance = self.mock_proxy.return_value
        self.proxy_instance.json = json.loads(BOOK_JSON)

    def tearDown( self ):
        self.patcher.stop()

    def test_mock_works( self ):
        book_id = 55
        v = create_from_proxy( book_id )
        self.assertTrue( self.mock_proxy.called )
        ... more tests ...

inside bookstore.py:

from my.app.proxies import BookProxy

def create_from_proxy( self, id ):
    proxy = BookProxy(id)
    ...

However when I run this test as part of the entire suite of tests (python manage.py test) then the test fails because the bookstore.py code doesn't get the mock class injected and falls back to the actual code for BookProxy.

So there seems to be something stateful going on when all of the tests are run together, but I can't figure out what's causing the mock injection to fail. Other unit tests that use mock all seem to be cleaning up after theirselves (either using the decorator, the context, or the explicit patch object approach that I'm showing here).

Something like this ever been seen out there before?

Biforate answered 15/7, 2014 at 19:55 Comment(3)
Your test is patching my.app.models.bookstore.BookProxy but your code is using from my.app.proxies import BookProxy. So you're likely patching objects which happen to be the same when running the tests manually but not when running it with manage.py.Dissonancy
I'm not sure I know what to do differently yet. All of the tests are being run starting from manage.py (I have the command line calls in my original question). It feels like the package loading is different in django-nose (or is it straight nose?) for many tests vs. one in isolation, but I can't backup my claim here.Biforate
I had similar problem and this answer helped me: https://mcmap.net/q/1474472/-mocking-test-in-django-not-working-when-running-all-in-testcase-but-works-well-one-by-oneTbilisi

© 2022 - 2024 — McMap. All rights reserved.