3

Anyone have ideas on how to mock a boto3 secrets manager client's get_secret_value method in a separate method without passing the client to the method? Stuck on this for days, now. Any ideas, links to possible working code on github would be appreciated.

fedonev
  • 20,327
  • 2
  • 25
  • 34
E K
  • 31
  • 1

1 Answers1

1

Boto3 has its own stubs, however i prefer to use python unittest.mock like below:

Your code in my_app

import boto3


def call_under_test():
    sm = boto3.client('secretsmanager')
    sm.get_secret_value(SecretId='my-secret')

Your test may look like below:

from unittest.mock import Mock, patch

import my_app


@patch('my_app.boto3.client')
def test_get_secret(mock_client: Mock):
    secret = {'SecretString': 'some-secret'}
    mock_client.return_value.get_secret_value.return_value = secret
    my_app.call_under_test()  # here is you unit to test
    mock_client.assert_called_with('secretsmanager')
    mock_client().get_secret_value.assert_called_with(SecretId='my-secret')


Anton
  • 1,432
  • 13
  • 17
  • 1
    This is an excellent answer. In my case I was using pytest's [monkeypatch](https://docs.pytest.org/en/stable/how-to/monkeypatch.html) rather than unittest's patch, but what I was missing was the first `return_value` for the mock_client (forgetting that the `boto3.client` is actually a function). Either way this is so much simpler and idiomatic than using the stubber and/ or moto or similar. Nice work. – followben May 22 '23 at 22:01