Javier Lopez Tomas
Javier Lopez Tomas

Reputation: 2362

How to mock a method from the same class that the method being tested?

I have the following project structure

repo
|
|--utils
|----hudi.py
|----__init__.py
|--tests
|----test_hudi.py
|----__init__.py

I want to test the class in hudi.py, which is:

class Partitions:
    def __init__(self, bucket, table)
        self.bucket = bucket
        self.table = table
    
    def get_partitions(self):
        return [
            f"s3://{self.bucket}/{self.table}{i}" 
            for i in list(range(10))
            if self.path_exists(i)
        ]

    def path_exists(self, i):
        s3_paths = code using external libraries
        if s3_paths:
            return True
        else:
            return False

I have written the code for testing in the file test_hudi.py as follow:

from utils import hudi

class TestHudi(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        cls.hudi_partitions = hudi.Partitions(
            table="signal",
            bucket="bkt_name",
        )

    def test_get_partitions(self):
        p = self.hudi_partitions.get_partitions()
        assert p = ["s3://bkt_name/signal1"]

For being able to execute the test as above, I need to mock the function path_exist, and make its returned value true, so I have tried to mock it with the following patches:

@mock.patch("utils.hudi.path_exists", return_value=True)
@mock.patch("utils.hudi.partitions.path_exists", return_value=True)
@mock.patch("hudi_partitions.path_exists", return_value=True)
@mock.patch("hudi.partitions.path_exists", return_value=True)
@mock.patch("hudi.path_exists", return_value=True)

And none of them work.

Is there any way I can mock the function path_exists? Thanks!

Upvotes: 0

Views: 1222

Answers (1)

Nicolas Hasbun
Nicolas Hasbun

Reputation: 21

To my understanding you should be mocking the use of external library. Also, this way you can test what happens when path does or doesn't exist.

If you still would like to accomplish this consider the following. You can actually replace a class function reference in python quite easily:

>>> class Test:
...   def dummy(self):
...     print("Original Test")
...
>>> test = Test()
>>> test.dummy()
Original Test
>>> def new_dummy():
...   print("New Test")
...
>>> test.dummy = new_dummy
>>> test.dummy()
New Test

Upvotes: 1

Related Questions