4

I am trying to write a test case test_is_user_present() which calls another function execute_redshift_sql() from redshift_util.py script

I set the expected return value from the function execute_redshift_sql() to 1 . But I never get this value returned from result after the function is called ! I also printed some values for debugging purpose

You can take a look at test case below

from mock import patch, Mock, MagicMock
from cia_admin_operations.redshift_util import  execute_redshift_sql
    @patch('cia_admin_operations.redshift_util.execute_redshift_sql')
    def test_is_user_present(mock_execute_redshift_sql):
        ldap_user = "dummy_user"
        mock_out = Mock()

        user_check_sql = "SELECT COUNT(1) FROM pg_user WHERE usename = '{}';".format(ldap_user)

        mock_execute_redshift_sql.return_value = 1
        print(mock_execute_redshift_sql())

        result = execute_redshift_sql(mock_out, user_check_sql)
        print(result)
        print(result())
>       assert result() == 1
E       AssertionError: assert <Mock name='m...749067684720'> == 1
E         -<Mock name='mock.query().getresult()()' id='139749067684720'>
E         +1

test/test_cia_admin_operations.py:51: AssertionError
----------------------------- Captured stdout call -----------------------------
1
<Mock name='mock.query().getresult()' id='139749067684776'>
<Mock name='mock.query().getresult()()' id='139749067684720'>

redshift_util.py

def execute_redshift_sql(connection, sqlQuery):
    """Executes redshift query"""

    logger.info("Executing following SQL query :\n %s" % sqlQuery)

    try:
        result = connection.query(sqlQuery)
        logger.info("Redshift query is successfully executed.")
    except Exception as e:
        logger.error("Query not executed : %s" % e)
        return None
    # return only if the result has some data
    if result:
        logger.info("Query result :\n %s" % result)
        return result.getresult()
    else:
        return 0
8
  • That looks like the function imported in the test wasn't mocked - how do you import it? Apart from that, I don't understand what the test shall do, but I guess this is just a dummy version of the real test. Commented Mar 27, 2020 at 18:33
  • @MrBeanBremen: This is dummy version of test only. The imported function (cia_admin_operations.redshift_util.execute_redshift_sql) is mocked thats why you see this printed name='mock.query().getresult()' . What I am expecting is the function should return the return value I set for testing purpose. Commented Mar 28, 2020 at 1:47
  • Well, no, the function is not mocked. What you see is the result of the mocked argument mock_out in the unmocked function. The used function seems not to be the same as the mocked one, thus I asked to show how it is imported. Commented Mar 28, 2020 at 5:48
  • @MrBean Bremen: do you mean this function : execute_redshift_sql ? how do i mock this function to give a specific return value ? Commented Mar 29, 2020 at 8:21
  • Yes, I mean this function, and I suspect that you mock not the one you imported. Thus I asked you to show how you import it. Please add the respective import to the question. Commented Mar 29, 2020 at 8:29

1 Answer 1

8
+100

You have to patch the function as it is imported. One possibility to fix this is to use:

from mock import patch, Mock
import cia_admin_operations.redshift_util

@patch('cia_admin_operations.redshift_util.execute_redshift_sql')
def test_is_user_present(mock_execute_redshift_sql):
    ldap_user = "dummy_user"
    mock_out = Mock()

    user_check_sql = "SELECT COUNT(1) FROM pg_user WHERE usename = '{}';".format(ldap_user)

    mock_execute_redshift_sql.return_value = 1

    result = cia_admin_operations.redshift_util.execute_redshift_sql(mock_out, user_check_sql)
    print(result)

In your case, you had mocked the function from the package, but used a locally imported module. You always have to check where to patch.

Above, I adapted the import, you can also adapt the patching:

from mock import patch, Mock
from cia_admin_operations.redshift_util import execute_redshift_sql

@patch('redshift_test.execute_redshift_sql')
def test_is_user_present(mock_execute_redshift_sql):
    ldap_user = "dummy_user"
    mock_out = Mock()

    user_check_sql = "SELECT COUNT(1) FROM pg_user WHERE usename = '{}';".format(ldap_user)

    mock_execute_redshift_sql.return_value = 1

    result = execute_redshift_sql(mock_out, user_check_sql)
    print(result)

(you have to substitute redshift_test for the name of your test module in the patch decorator)

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

2 Comments

Excellent ! this line worked `` cia_admin_operations.redshift_util.execute_redshift_sql(mock_out, user_check_sql)`` Missed to call with package !
This really help me understand how patching works! I've been using patch all along and did not find it a problem. As stated The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined. Obviously, it is easy to fall into this problem when refactoring a big class into smaller classes.

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.