How to mock environment variables and packages before importing Python script using pytest tests?

Viewed 97

I am using pytest to test out an AWS Lambda function I am writing. The function has some initialization code outside of any function. It looks similar to this:

catalog_service/lambda_v1.py

import boto3
import botocore
import json
import os

from aws_lambda_powertools import Logger
from elastic_enterprise_search import AppSearch


LOGGER = Logger()
ENV = os.environ['ENVIRONMENT']
ssm = boto3.client('ssm')
key_response = ssm.get_parameter(
    Name=key,
    WithDecryption=True
    )
APP_SEARCH = AppSearch(
    os.environ['APP_SEARCH_API_HOST'],
    bearer_auth=key_response['Parameter']['Value'],
    )

# Additional functions

Whenever I run my test, it always fails with a KeyError saying that ENVIRONMENT is not in os.environ which makes sense since I believe it's importing the Lambda script before running any of the other mocking code. Whenever I try to mock it with monkeypatch it seems like I am not doing it in the right spot. My test looks like this:

import pytest
import os
from . import fixtures
from catalog_service import lambda_v1 as v1

@pytest.fixture
def mock_set_environment(monkeypatch):
    monkeypatch.setenv('ENVIRONMENT', 'qa')

class TestLambdaV1:
    @pytest.mark.parametrize('data, expected', [
        (
            {'a': 1},
            {
                'statusCode': '200',
                'headers': {
                    'content-type': 'application/json'
                    },
                'body': '{"a": 1}'
                },
            ),
        ])
    def test_format_good_response(self, mock_set_environment, data, expected):
        assert os.getenv('ENVIRONMENT') == 'qa'
        result = v1.format_good_response(data)
        assert result == expected

I think it would mock the environment variable if it were being used within the function but it is used during the import. How do I mock the os.environ variable as well as the AppSearch and boto3 packages before they're imported / used?

0 Answers
Related