3

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()

2
  • Mock out the calls to redis and assert the correct methods were called on the mock Commented Dec 31, 2020 at 10:51
  • One of the functions I have to test have code related to flask caching for retrieving the data and processing it. So, I won't be able to write unit tests for that. Don't have different function to just retrieve redis data. Commented Dec 31, 2020 at 10:56

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Can you pls. explain the difference between function_to_mock and mock_function_to_mock in the second example ?
@Simplecode function_to_mock is the target function to mock, so that it's not actually called. I believe for your case function_to_mock is func2(). mock_function_to_mock is the MagicMock instance created by patch() for function_to_mock. In other words, patch() replaces function_to_mock with a MagicMock instance, which is then passed to the test function test_redis() via the mock_function_to_mock parameter. mock_function_to_mock can then be used to specify returned values.
Is this necessary to use mock_func2.assert_called_once() ?
@Simplecode It's not necessary to call mock_func2.assert_called_once() as it only checks that func2 is called only once inside of func_1(). If you don't want to check this, then it can be left out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.