-1

I was writing a test using pytest library where I need to test a method which takes another method as an argument.

class Certificate:
    def upload(self, upload_fn: Callable):
        try:
            if self.file_name:
                upload_fn(self.file_name)
                return

            raise ValueError("File name doesn't exist")
        except Exception as e:
            raise e

Now I created a dummy mock function which I am passing while calling upload method but I am not sure how do I make sure if the upload_fn is called.

I am trying to achieve something like this

def test_certificate_upload(certificate):
    certificate.upload(some_mock_fn)
    assert some_mock_fn.called_once() == True

EDIT: so currently I am testing it in the following way but I think there can be a better approach.

def mock_upload(f_name):
    ""just an empty mock method""

def mock_upload_raise_error(f_name):
    raise Exception e

def test_certificate_upload_raise_exception(certificate):
    with pytest.raises(Exception) as e:
        certificate.generate(mock_generator_raise_error)

PS: limitation to this approach is we can't assert if the method was called or how many times the method was called or with what params the method was called.

Also, we have to create extra dummy mock methods for differnet scenarios.

BL_NK
  • 69
  • 1
  • 8
  • 1
    you can try mocking the function call with unittest's mock.patch and then on the mock object, you can do mock_object.assert_called() / mock_object.assert_called_with() – Vikrant Srivastava Aug 26 '22 at 07:45
  • [assert_called](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.assert_called) – timgeb Aug 26 '22 at 07:47

1 Answers1

0

You an mock :

def mock_get(self, *args):
    return "Result I want"


@mock.patch(upload, side_effect=mock_get)
def test_certificate_upload(certificate):
    certificate.upload(some_mock_fn)
    assert function_name() == Return_data
Harsha Biyani
  • 7,049
  • 9
  • 37
  • 61
  • thanks @Harsha for your answer, but since upload_fn is just an argument we can't actually refer to the path where its called since its just an argument passed in genrate method. we will get function object has no attribute upload_fn error while running the test(since its a parameter) – BL_NK Aug 29 '22 at 07:00
  • what you are expecting from `upload` that you have to modify in `mock_get` function. Its a parameter to `mock` decorator. So whenever upload is calling in a function, whatever you are returning in `mock_get` that will get return. Actual function will not get call. – Harsha Biyani Aug 29 '22 at 07:36
  • I agree to your concept, but here I want to test upload() method so I need to call it. inside upload we are calling the callable argument which needs to be passed as an argument to upload method. – BL_NK Aug 29 '22 at 08:01
  • https://stackoverflow.com/questions/16162015/mocking-python-function-based-on-input-arguments – Harsha Biyani Aug 29 '22 at 13:07