I am bothering with some mock while I am testing python class in module, I have provided an example below
While I am having such module's structure:
mock_example/
source/
module_A/
__init__.py
A.py
test/
__init__.py
test_a.py
Let's say that module_A
contains A.py
with class A with such definition:
from robot.libraries.BuiltIn import BuiltIn # some external module
class A:
def __init__(self):
self._some_attribute = BuiltIn()
def some_method(self, variable_name):
return self._some_attribute.get_variable_value(variable_name)
but module_A's init.py narrows namespace by setting inside:
from source.module_A.A import A
I am just trying to test A class in test/
location.
In class constructor, You can see that some of my attribute is assigned to external module's imported class and instance is being imported. My point of interest is how to mock external module assigned in A class constructor but with such __init__.py
file so class instance from external module won't be created and will be mocked. Is it even possible if my __init__.py
of module_A
allows me only to import A
class?
The question
How can I mock A's _some_attribute
so in test_a.py
:
from mock import Mock
def test_a_class_instance():
instance = A()
instance
won't create instance BuiltIn
but it would be mocked atribute?
What I have tried?
I've been trying to mock external BuiltIn
module globally by trying to mess with sys.modules:
import sys
import types
from mock import Mock
module_name = 'robot.libraries.BuiltIn'
module_mock = types.ModuleType(module_name)
sys.modules[module_name] = module_mock
builtin_mock = Mock()
builtin_ctor_mock = Mock(name=module_name + '.BuiltIn', return_value=builtin_mock)
module_mock.BuiltIn = builtin_ctor_mock
and then importing it in test_a.py
with import over class import that would be tested, but without any luck.
The only way I can see to mock this is to let BuiltIn
instance be created and then override this with mock or totally remove content of __init__.py
of module_A
directory, but I would like not to intervene in source code only because I got bitten by mock :)
Any tips would be more than welcome!
The pattern for unit testing with an external dependency is that you pass the dependency as a constructor argument, and if it is null (None
), initialize it inside the constructor. This enables you to pass a mock from your unit test for this dependency with whatever behavior you want preconfigured.