How to properly patch boto3 calls in unit test

2024/11/13 10:05:32

I'm new to Python unit testing, and I want to mock calls to the boto3 3rd party library. Here's my stripped down code:

real_code.py:

import boto3def temp_get_variable(var_name):return boto3.client('ssm').get_parameter(Name=var_name)['Parameter']['Value']

test_real_code.py:

import unittest
from datetime import datetime
from unittest.mock import patchimport real_codeclass TestRealCode(unittest.TestCase):@patch('patching_config.boto3.client')def test_get_variable(self, mock_boto_client):response = {'Parameter': {'Name': 'MyTestParameterName','Type': 'String','Value': 'myValue','Version': 123,'Selector': 'asdf','SourceResult': 'asdf','LastModifiedDate': datetime(2019, 7, 16),'ARN': 'asdf'}}mock_boto_client.get_variable.return_value = responseresult_value = real_code.get_variable("MyTestParameterName")self.assertEqual("myValue", result_value)

When I run it the test fails with

Expected :myValue
Actual   :<MagicMock name='client().get_parameter().__getitem__().__getitem__()' id='2040071816528'>

What am I doing wrong? I thought by setting mock_boto_client.get_variable.return_value = response it would mock out the call and return my canned response instead. I don't understand why I am getting a MagicMock object instead of the return value I tried to set. I'd like to set up my test so that when the call to get_parameter is made with specific parameters, the mock returns the canned response I specified in the test.

Answer

There are two issues with your test code. The first is that when your mock object mock_boto_client called, it returns a new mock object. This means that the object that get_parameter() is being called on is different than the one you are attempting to set a return value on. You can have it return itself with the following:

mock_boto_client.return_value = mock_boto_client

You can also use a different mock object:

foo = MagicMock()
mock_boto_client.return_value = foo

The second issue that you have is that you are mocking the wrong method call. mock_boto_client.get_variable.return_value should be mock_boto_client.get_parameter.return_value. Here is the test updated and working:

import unittest
from datetime import datetime
from unittest.mock import patchimport real_codeclass TestRealCode(unittest.TestCase):@patch('boto3.client')def test_get_variable(self, mock_boto_client):response = {'Parameter': {'Name': 'MyTestParameterName','Type': 'String','Value': 'myValue','Version': 123,'Selector': 'asdf','SourceResult': 'asdf','LastModifiedDate': datetime(2019, 7, 16),'ARN': 'asdf'}}mock_boto_client.return_value = mock_boto_clientmock_boto_client.get_parameter.return_value = responseresult_value = real_code.get_variable("MyTestParameterName")self.assertEqual("myValue", result_value)
https://en.xdnf.cn/q/72339.html

Related Q&A

import a github into jupyter notebook directly?

Hey Im creating a jupyter notebook, would like to install: https://github.com/voice32/stock_market_indicators/blob/master/indicators.py which is a python program not sure how to do it directly so anybo…

Django : Call a method only once when the django starts up

I want to initialize some variables (from the database) when Django starts. I am able to get the data from the database but the problem is how should I call the initialize method . And this should be o…

Mocking instance attributes

Please help me understand why the following doesnt work. In particular - instance attributes of a tested class are not visible to Pythons unittest.Mock.In the example below bar instance attribute is no…

Are there any good 3rd party GUI products for Python? [closed]

Closed. This question is seeking recommendations for books, tools, software libraries, and more. It does not meet Stack Overflow guidelines. It is not currently accepting answers.We don’t allow questi…

not able to get root window resize event

im trying to display the size(dimension) of the root window (top level window) on a label. whenever the user resize the window, new window dimensions should be displayed on the label. I tried to bind t…

Inverting large sparse matrices with scipy

I have to invert a large sparse matrix. I cannot escape from the matrix inversion, the only shortcut would be to just get an idea of the main diagonal elements, and ignore the off-diagonal elements (Id…

Error with tweepy OAuthHandler

Im new here and kind of unexperienced with python, so sorry if the question is trivial.I have this simple script, to fetch followers of a given twitter user:import time import tweepyconsumer_key="…

Overriding __or__ operator on python classes

As a contrived example, suppose Im generating a random fruit basket in python. I create the basket:basket = FruitBasket()Now I want to specify specific combinations of fruit that can occur in the baske…

python charmap codec cant decode byte X in position Y character maps to undefined

Im experimenting with python libraries for data analysis,the problem im facing is this exceptionUnicodeDecodeError was unhandled by user code Message: charmap codeccant decode byte 0x81 in position 165…

get icloud web service endpoints to fetch data

My question may look silly but I am asking this after too much search on Google, yet not have any clue.I am using iCloud web services. For that I have converted this Python code to PHP. https://github.…