Question: I have the following dataclass: import os import dataclasses @dataclasses.dataclass class Example: host: str = os.environ.get('SERVICE_HOST', 'localhost') port: str = os.environ.get('SERVICE_PORT', 30650)  How do I write a test for this? I tried the following which looks like it should work: from stackoverflow import Example import os def test_example(monkeypatch): # GIVEN environment variables are set for host and port monkeypatch.setenv('SERVICE_HOST', 'server.example.com') monkeypatch.setenv('SERVICE_PORT', '12345') # AND a class instance is initialized without specifying a host or port example = Example() # THEN the instance should reflect the host and port specified in the environment variables assert example.host == 'server.example.com' assert example.port == '12345'  but this fails with: ====================================================================== test session starts ====================================================================== platform linux -- Python 3.8.12, pytest-7.1.2, pluggy-1.0.0 rootdir: /home/biogeek/tmp collected 1 item test_example.py F [100%] =========================================================================== FAILURES ============================================================================ _________________________________________________________________________ test_example __________________________________________________________________________ monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f39de559220> def test_example(monkeypatch): # GIVEN environment variables are set for host and port monkeypatch.setenv('SERVICE_HOST', 'server.example.com') monkeypatch.setenv('SERVICE_PORT', '12345') # AND a class instance is initialized without specifying a host or port example = Example() # THEN the instance should reflect the host and port specified in the environment variables > assert example.host == 'server.example.com' E AssertionError: assert 'localhost' == 'server.example.com' E - server.example.com E + localhost test_example.py:12: AssertionError ==================================================================== short test summary info ==================================================================== FAILED test_example.py::test_example - AssertionError: assert 'localhost' == 'server.example.com' ======================================================================= 1 failed in 0.05s ======================================================================= 

Answer: Your tests fail because your code loads the environment variables when you import the module. Module-level code is very hard to test, as the os.environ.get() calls to set the default values have already run before your test runs. You'd have to effectively delete your module from the sys.modules module cache, and only import your module after mocking out the os.environ environment variables to test what happens at import time. You could instead use a dataclass.field() with a default_factory argument; that executes a callable to obtain the default whenever you create an instance of your dataclass: import os from dataclasses import dataclass, field from functools import partial @dataclass class Example: host: str = field(default_factory=partial(os.environ.get, 'SERVICE_HOST', 'localhost')) port: str = field(default_factory=partial(os.environ.get, 'SERVICE_PORT', '30650'))  I used the functools.partial() object to create a callable that'll call os.environ.get() with the given name and default. Note that I also changed the default value for SERVICE_PORT to a string; after all, the port field is annotated as a str, not an int. :-) If you must set these defaults from environment variables at import time, then you could have pytest mock out these environment variables in a conftest.py module; these are imported before your tests are imported, so you get a chance to tweak things before your module-under-test is imported. This won't let you run multiple tests with different defaults, however: # add to conftest.py at the same package level, or higher. @pytest.fixture(autouse=True, scope="session") def mock_environment(monkeypatch): monkeypatch.setenv('SERVICE_HOST', 'server.example.com') monkeypatch.setenv('SERVICE_PORT', '12345')  The above fixture example, when placed in conftest.py, would automatically patch your environment before your tests are loaded, and so before your module is imported, and this patch is automatically undone at the end of the test session.