Search code examples
pythonunit-testingredispytestflask-caching

Mock redis for writing unittest for application


I have a flask application, in which I use "flask-caching" with redis. I save some values in the cache and retrieve it for processing. I have to write unittest for this. How can I mock the redis instance and pass the host for that server in the flask caching config.

I did try "fakeredis", but that does not give me the redis host, which I can use in flask caching and test my application.

How can I go about writing unit test cases for this ?

def func_1():
    # some steps
    x = func2() # this is where the code for flask caching (redis) data retrieval is
    # process x

I have to test func_1()


Solution

  • The mock object library can be used to create a Mock instance for Redis that returns a value for a particular method call, for example:

    from unittest.mock import Mock
    
    def test_redis():
        mock_redis = Mock()
        mock_redis.get.return_value = "2020-12-31T00:00:00".encode()
    
        function_to_test(mock_redis)
    

    If a function needs to be mocked, so that the function is not actually called, and is used inside the function that is being tested, the patch decorator can be used, as follows:

    from unittest.mock import patch
    
    @patch("package.module.function_to_mock")
    def test_redis(mock_function_to_mock):
        mock_function_to_mock.get.return_value = "2020-12-31T00:00:00".encode()
    
        function_to_test()
    

    This could be used to mock the flask caching related code that is inside the function that you are testing.


    Edit

    For your case, I believe you may want to do the following:

    from unittest.mock import patch
    
    @patch("package.module.func2")
    def test_func_1(mock_func2):
        mock_func2.return_value = "Test value"
    
        func_1()
    
        mock_func2.assert_called_once()
    

    Here func2() is mocked and it's return value is set to "Test value", so when it is called inside of func_1() variable x equals "Test value"

    Note: the path passed to patch() must be to where func2() is imported, and not to the module where func2() is defined.