Search code examples
pythonunit-testingmockingpython-unittestpatch

fetch different values in each function for the same sqlclient object in python unittest


I am trying to perform an integration test on the project. We have a mysqlclient object which is mocked and able to assign dummy values on the first fetchall call. Can anyone help me in how to fetch different values each time the fetchall is called in different functions. the code structure is as below.

test function


@mock.patch("src.calculate.get_mysql_connection", return_value = mock.Mock())
@mock.patch("src.calculate.get_mongo_connection", return_value = mock.Mock())
def test_initiate_calc(self, mongo_patcher, mysql_patcher):
    mysql_patcher.return_value.\
            execute_query.return_value.\
            fetchall.return_value = [1,2,3,4]
    
    test_main()

main function


main():
    mongo_client = get_mongo_connection() 
    mysql_client = get_mysql_connection() - - - - - mocked mysql object
    func1(mysql_client)
    func2(mysql_client)
    func3(mysql_client)
    func4(mysql_client)

func1(mysql_client):
    query = ("select something")

    params = (some_params, )

    cursor = mysql_client.execute_query(query, params)

    result1 = cursor.fetchall() - - - - - This works as intended and returns [1,2,3,4]

func2(mysql_client):
    query = ("select something")

    params = (some_params, )

    cursor = mysql_client.execute_query(query, params)

    result2 = cursor.fetchall() - - - - - how to mock different value here for the same 

func3(mysql_client):
    query = ("select something")

    params = (some_params, )

    cursor = mysql_client.execute_query(query, params)

    result3 = cursor.fetchall() - - - - - how to mock different value here for the same


Can anyone help me in how to fetch different values each time the fetchall is called in different functions


Solution

  • You can create whole mocking function. There you can easily set what you want to get on various conditions.

    from unittest.mock import patch
    def mocked_connection():
      class MockedCursor:
        def fetchall(self):
          # This will enable you to change return each next call
          global x
          x += 1
          if x == 1:
            return [1,2,3,4]
          elif x == 2:
            return [2,3,4,5]
    
      class MockedConnection:
        def execute_query(self, query, params):
          return MockedCursor()
      return MockedConnection()
    
    
    # Then use this mocked connection
    @patch("src.calculate.get_mysql_connection", mocked_connection)
    @patch("src.calculate.get_mongo_connection", mocked_connection)
    def test_initiate_calc(self, mongo_patcher, mysql_patcher):
        x = 0
        test_main()