Unit tests (python)

Introduction

Framework 'unittest' is part of Python standard library since Python 2.1.

The another framework Python has is 'PyTest'. 


https://tox.wiki/en/latest/


Reference

A Beginner’s Guide to Unit Tests in Python (2023)

Note: Where it says 'should contain an init.py file' it works fine with a empty __init__.py one (eg: cou sixqueue)

https://www.dataquest.io/blog/unit-tests-python/

Python Mock Cookbook 

https://chase-seibert.github.io/blog/2015/06/25/python-mocking-cookbook.html

Samples

Big Upfront Caveat (from the Python Mock Cookbook):

"The biggest mistake people make is mocking something out in the wrong place. You always need to mock the thing where it’s imported TO, not where it’s imported FROM. Translation: if you’re importing from foo import bar into a package bat.baz, you need to mock it as @mock.patch('bat.baz.bar'). This can be confusing if you think you should be mocking it where it’s defined, not where it’s used."


Mock a function

Eg: cou sixqueue

The mocked function:

def mocked_get_ssm_salesforce(*args, **kwargs):

    """SalesforceClient.get_ssm_salesforce(name: str)

    """

    pName = args[0]

    env = config_mock['env']

    ci = config_mock['ci']

    print('DEBUG mocked_get_ssm_salesforce:', pName, env, ci)


    if pName == "/{env}/{ci}/salesforce_url_login".format(env=env, ci=ci):

        return config_mock['SALESFORCE_URL_LOGIN']

    elif pName == "/{env}/{ci}/salesforce_client_id".format(env=env, ci=ci):

        return config_mock['SALESFORCE_CLIENT_ID']

    elif pName == "/{env}/{ci}/salesforce_client_secret".format(env=env, ci=ci):

        return config_mock['SALESFORCE_CLIENT_SECRET']

    elif pName == "/{env}/{ci}/salesforce_username".format(env=env, ci=ci):

        return config_mock['SALESFORCE_USERNAME']

    elif pName == "/{env}/{ci}/salesforce_password".format(env=env, ci=ci):

        return config_mock['SALESFORCE_PASSWORD']

    elif pName == "/{env}/{ci}/salesforce_token".format(env=env, ci=ci):

        return config_mock['SALESFORCE_TOKEN']

    else:

        return config_mock[pName] #doesn't make much sense but it should never be executed


and where it is used:

class MockTestCase(unittest.TestCase):

    sol_info = json.load(open(os.path.join(here, 'test_tutoritzacio_matricula.json')))


    def setUp(self):

        os.environ['env'] = config_mock['env']

        os.environ['ci'] = config_mock['ci']


    @mock.patch('src.jsonapi.cuacrm.dispatcher_crm.SalesforceClient.get_ssm_salesforce', side_effect=mocked_get_ssm_salesforce)

    @mock.patch('src.jsonapi.cuacrm.common.salesforce.requests.post', side_effect=mocked_requests_post_great)

    def test_entry_great(self, mock_post, mock_get_ssm_salesforce):

        mgc = MockClass()

        result, text = mgc.execute(self.sol_info, logger)

        logger.info('RESULT: ' + str(result))

        logger.info('MESSAGE: ' + str(text))

        self.assertEqual(result, status['PROCESSED'])

        self.assertTrue(text['crm_result'])

        crm_result = text['crm_result']

        self.assertEqual(crm_result['codeResult'], 'OK')

        self.assertTrue(crm_result['msgResult'])

        self.assertTrue(crm_result['idTransaction'])

        self.assertTrue(crm_result['personCode'])

        self.assertTrue(crm_result['opportunityCode'])