This does not work
@pytest.fixture(scope="module")
def monkeypatch_module():
# gross bug: https://github.com/pytest-dev/pytest/issues/363
from _pytest.monkeypatch import MonkeyPatch
mpatch = MonkeyPatch()
yield mpatch
mpatch.undo()
@pytest.fixture(scope="module")
@mock_secretsmanager
def setup_stuff(monkeypatch_module):
secret_name = "test_mock_secret01"
sm_client = boto3.client("secretsmanager", region_name="us-east-1")
sm_client.create_secret(
Name=secret_name,
SecretString='{"username":"mockuser","password":"mockpass"}',
)
# module level env vars
monkeypatch_module.setenv("MY_VAR", "sldkfjsdf")
@pytest.mark.unittest
def test__mytest(setup_stuff):
secret_name = "test_mock_secret01"
my_method_that_gets_the_secret(secret_name)
I get this error:
botocore.errorfactory.ResourceNotFoundException: An error occurred (ResourceNotFoundException) when calling the GetSecretValue operation: Secrets Manager can't find the specified secret.
I had to make it a function and use it like this:
@mock_secretsmanager
def setup_stuff(monkeypatch_module):
secret_name = "test_mock_secret01"
sm_client = boto3.client("secretsmanager", region_name="us-east-1")
sm_client.create_secret(
Name=secret_name,
SecretString='{"username":"mockuser","password":"mockpass"}',
)
# module level env vars
monkeypatch_module.setenv("MY_VAR", "sldkfjsdf")
@mock_secretsmanager
@pytest.mark.unittest
def test__mytest(monkeypatch, monkeypatch_module):
setup_stuff(monkeypatch_module)
# function level env vars
monkeypatch.setenv("MY_LOCAL_VAR", "sldkfjsdf")
But this will run with every function call.
I just want to create a fixture that creates mock secrets (sets env vars and other stuff) once for the entire module.
What is the proper way to use mock_secretsmanager
in a module scoped fixture?
Moto resets its internal state, every time a mock starts and ends. This is necessary to ensure that state doesn't leak in between tests.
Adding mock_secretsmanager
to setup_stuff
ensures that these secrets exist for the duration of that particular method - but the moment the method/mock ends, it will delete the state again.
Your solution, to yield a mock and pass that to a method, ensures that the with mock_secretsmanager()
context is started at the beginning of the test, and active for the entire duration. That's why it works.
Note that this is indeed the recommended approach when using fixtures: see http://docs.getmoto.org/en/latest/docs/getting_started.html#recommended-usage