I'm trying to create some pytest unit tests on a custom ansible module. I'm trying to mock the boto3 client and just test the logic of the class. I moved the initialization of boto into a class method so I can patch the class and replace it with a mock object.
Patch seems to be successful, the "_init_boto" method is returning a mock object. But I can't figure out how to set the return value so that "describe_stacks(..)" returns a custom reponse, or assert on the calls on the mock. Sample code:
cf_stack_exists.py:
import boto3
class CfStackExistsSimplified:
def __init__(self, aws_profile) -> None:
super().__init__()
self.aws_profile = aws_profile
self.boto_client = self._init_boto(aws_profile)
def _init_boto(self):
session = boto3.session.Session(profile_name=self.aws_profile)
return session.client('cloudformation')
def exec(self):
response = self.boto_client.describe_stacks(
StackName=self.aws_profile
)
return response
test_myclass.py:
from unittest.mock import patch
from cf_stack_exists import CfStackExistsSimplified
class TestCfStackExists:
@patch.object(CfStackExistsSimplified, "_init_boto")
def test_example(self, mock_init_boto):
myclass = CfStackExistsSimplified(aws_profile="dev")
response = myclass.exec()
print(f"\n{mock_init_boto.mock_calls}\n")
mock_init_boto.describe_stacks().assert_called()
When I run this it fails with the error:
...
> raise AssertionError(msg)
E AssertionError: Expected 'mock' to have been called.
...
But the print statement is showing that it has been called?
[call('dev'), call().describe_stacks(StackName='dev')]
I really can't figure out how to assert this mock, tried lots of different assert commands. Any help much appreciated!!