Search code examples
pythonpytestpydanticpytest-mock-patch

How can I mock my environment variables for my pytest?


I've looked at some examples to mock environment variables. Here

In my case, I have to mock a variable in my config.py file that is setup as follows:

class ServiceConfig(BaseSettings):
   ...
   API_AUDIENCE: str = os.environ.get("API_AUDIENCE")
   ... 
   ...  

I have that called here:

class Config(BaseSettings):  
auth: ClassVar[ServiceConfig] = ServiceConfig()

I've attempted to patch that value as follows:

@mock.patch.dict(os.environ, {"API_AUDIENCE": "https://mock.com"})
class Test(TestCase):

Another way I've tried is:

@patch('config.Config.API_AUDIENCE', "https://mock.com")
def ....:

The setup is incorrect both ways, getting this error:

E   pydantic_core._pydantic_core.ValidationError: 1 validation error for 
ServiceConfig
E   API_AUDIENCE

What is the correct way to setup mocking an environment variable?


Solution

  • To update the environment, and restore it after the test:

    import os
    from unittest import mock
    
    @pytest.fixture()
    def setenvvar(monkeypatch):
        with mock.patch.dict(os.environ, clear=True):
            envvars = {
                "API_AUDIENCE": "https://mock.com",
            }
            for k, v in envvars.items():
                monkeypatch.setenv(k, v)
            yield # This is the magical bit which restore the environment after 
    

    This is just a fixture, you can use it (or not) in any test you want, at the scope you want, no extra dependencies.