Reputation: 12152
I want to make my tests "real" unittests in a strict meaning. There shouldn't be any dependencies. All dependencies should be mocked.
The class Bar
in module bar
need to be tested. But in some situations it will have a member of type Foo
from module foo
. The goal is that the unittest does not have to import foo
or foo.Foo
.
My mocking seems to work. But I'm not sure how to test if Bar()
now does have tried to instantiate foo.Foo()
. My assert_called()
in the below example failed with Expected 'mock' to have been called.
. And that assert also doesn't give me all information's I want.
This is the test code:
#!/usr/bin/env python3
import unittest
from unittest import mock
import bar
# The goal ist to test "Bar" wihtout importing "foo.Foo" as an extra dependency
class MyTest(unittest.TestCase):
def test_bar(self):
mock_foo = mock.Mock()
bar.foo = mock_foo
b = bar.Bar(7)
print('')
print(f'{mock_foo=}')
print(f'{b.y=}')
# Of course this doesn't work, because "foo" is not imported
# self.assertIsInstance(b.y, foo.Foo)
print(mock_foo.__dict__)
mock_foo.assert_called() # failes
def test_int(self):
b = bar.Bar(8)
self.assertIsInstance(b.y, int)
if __name__ == '__main__':
unittest.main()
Here comes module bar
:
import foo
class Bar:
def __init__(self, y):
if y == 7:
self.y = foo.Foo(7)
else:
self.y = y
And this is module foo
:
class Foo:
def __init__(self, x):
self.x = x
Upvotes: 0
Views: 71
Reputation: 117
When you're mocking, you should really be using mock.patch()
to do your patching.
consider, instead:
#!/usr/bin/env python3
import sys
import unittest
from unittest import mock
import bar
class MyTest(unittest.TestCase):
@mock.patch('foo.Foo')
def test_bar(self, foo_mock):
b = bar.Bar(7)
# This _does_ work, because the patch decorator gives us the patched
# mock.
# this is something you should _never_ include in a proper unit test,
# but here to demonstrate the patching
self.assertIs(foo_mock, sys.modules['foo'].Foo)
foo_mock.assert_called_once_with(7)
def test_no_foo(self):
for test_val in [0, True, False, None, 13, 666]:
with self.subTest(test_val=test_val):
b = bar.Bar(test_val)
self.assertEqual(b.y, test_val)
if __name__ == '__main__':
unittest.main()
Upvotes: 1