Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to mock a class during a unittest – in the factory method?

How can I mock the class "ClassA" in the test by replacing it completely
If I have a class created through a factory method?

├── main.py
├── src
│   ├── core.py
│   ├── facade.py
│   ├── factory.py
│   └── something
│       ├── class_a.py
│       ├── class_b.py
│       ├── class_c.py
│       └── interface.py
└── tests
    └── test_core.py

class_a.py

from src.something.interface import Interface


class ClassA(Interface):

    def function(self):
        print('I\'m class A')

class_b.py

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

from src.something.interface import Interface


class ClassB(Interface):

    def function(self):
        print('I\'m class B')   

 

class_c.py

class ClassC:

    def function(self):
        print('I\'m class C')  

  

interface.py

from abc import ABC, abstractmethod


class Interface(ABC):

    @abstractmethod
    def function(self):
        pass

facade.py

from src.something.class_c import ClassC
from src.something.interface import Interface


class Facade:
    def __init__(self, interface: Interface, class_c: ClassC):
        self.function = interface
        self.class_c = class_c

    def functionClass(self):
        self.function.function()

    def functionAnotherClass(self):
        self.class_c.function()  

  

factory.py

from src.facade import Facade
from src.something.class_a import ClassA
from src.something.class_b import ClassB
from src.something.class_c import ClassC


class Factory:
    @staticmethod
    def build(config: str):
        if config == 'A':
            return Facade(ClassA(), ClassC())
        elif config == 'B':
            return Facade(ClassB(), ClassC())
        else:
            raise ValueError("Error factory")  


        
        

core.py

from src.factory import Factory


class Core:

    def __init__(self):
        self.__unit = Factory.build('A')

    def run(self):
        self.__unit.functionClass()
        self.__unit.functionAnotherClass()  

      

main.py

from src.core import Core

if __name__ == '__main__':
    core = Core()
    core.run()

test_core.py

import unittest
from unittest.mock import patch

from src.core import Core


class MockClassA:

    def function(self):
        print('I\'m mock class A')


class TestCore(unittest.TestCase):

    @patch('src.something.class_a.ClassA', new=MockClassA)
    def testOne(self):
        core = Core()
        core.run()
        pass

I expect that ClassA will be replaced with a mock class and the factory will send a locked object to the facade, however this does not happen when the test is run, it is output

OK

Process finished with exit code 0
I'm class A
I'm class C

Although I expect that it will be

Ran 1 test in 0.001s

OK

Process finished with exit code 0
I'm mock class A
I'm class C

can you tell me how to replace a class with such a code?

>Solution :

using ‘src.factory.ClassA’ instead of ‘src.something.class_a.ClassA’ or mocking the attribute of ClassA work, but the other one does not because the @patch does not change references of the class.

class TestCore(unittest.TestCase):

    @patch('src.factory.ClassA', new=MockClassA)
    def testOne(self):
        core = Core()
        core.run()
        pass

    @patch('src.something.class_a.ClassA.function', lambda _: print('I\'m mock 2 class A'))
    def testTwo(self):
        core = Core()
        core.run()
        pass
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading