0

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!

MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46
Javier Lopez Tomas
  • 2,072
  • 3
  • 19
  • 41
  • You don't. Don't mock parts of the thing you're supposed to be testing - test doubles are for _collaborators_. – jonrsharpe Apr 23 '22 at 14:36
  • You left out the most relevant detail related to patching here: what exactly is "code using external libraries". – chepner Apr 23 '22 at 15:17
  • Looks like a typo in your patch string, you seem to need `@mock.patch("utils.hudi.Partitions.path_exists", return_value=True)` - note the capitalization. Apart from that, it would indeed be cleaner to mock the external library instead. – MrBean Bremen Apr 23 '22 at 16:09

1 Answers1

1

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