Access a variable from setup_method in pytest - python-3.x

I am quiet new to pytest.
I have declared my Testclass as follows
class TestSerialPort():
#pytest.fixture(autouse=True)
def setupandtear(self,request):
obj = connect_serialport()
yield
obj.close()
def test_abc(self,setupandtear)
print ("object {}".format(obj.port))
I am seeing issue while accessing obj in test method. How can I access "obj" from setup to test_abc?

Related

Python unittest patch mocking class property

I am trying to patch a property of a class with some mock value, but when I run the test case the function or class that is using that property is not replacing it with the mock that I have created.
Module property that I need to mock
class Mymodule:
#property
async def calling_property(self):
return "Calling the property"
the class that is using this module.
class Usecase:
async def execute(self):
module = Mymodule()
data = await module.calling_property
print(data)
the test case I have written
import unittest
from unittest.mock import patch, AsyncMock,PropertyMock
class TestModule(unittest.IsolatedAsyncioTestCase):
async def test_execute(self):
with patch("Mymodule",
**{"calling_property":AsyncMock(return_value="calling mock")}, new_callable=PropertyMock
)as mock:
a = Usecase()
await a.execute()
As you can see i am logging the response from the property in my usecase, so when I run my test it is logging "calling the property" rather than "calling mock".
I tried another way.
class TestModule(unittest.IsolatedAsyncioTestCase):
async def test_execute(self):
with patch("Mymodule.calling_property",
new_callable=PropertyMock,
return_value= AsyncMock(return_value="calling mock")
)as mock:
a = A()
await a.execute()
This gives separate error
TypeError: object AsyncMock can't be used in 'await' expression
I have also tried creating a mock for the class object
class TestModule(unittest.IsolatedAsyncioTestCase):
async def test_execute(self):
with patch.object(Mymodule,
"calling_property",
new_callable=PropertyMock,
return_value=AsyncMock(return_value="calling mock")
)as mock:
a = A()
await a.execute()
TypeError: object AsyncMock can't be used in 'await' expression

Python Mock Instantiation of Object

Could someone please let me know how to mock the DatabaseAPI object for below unit test case example. Getting error at getURL in test_load.py file.
File load.py
from database_api import DatabaseAPI
Database_api_client = DatabaseAPI(username, password)
def loadFile():
#some code to load the file
File database_api.py
class DatabaseAPI:
def __init__(self, username, password):
self.getUrl()
def getUrl(self):
requests.options(url=SomeURL, headers=request_header)
File test_load.py
import unittest
from load import loadFile
class TestLoad(unittest.TestCase):
def test_loadFile(self):
#some code to test loadfile
But getting get_url connection error. I need to mock the "Database_api_client = DatabaseAPI(username, password)" object
But getting get_url connection error. I need to mock the "Database_api_client = DatabaseAPI(username, password)" object

mock secret manager using pytest

I am trying to mock secret manager. Here is the code which is written for secret manager using boto3 which I am trying to mock and test.
utils.py
import boto3
secret_id = os.environ.get("SECRETS")
client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId=secret_id)
secrets = json.loads(response['SecretString'])
S3_BUCKET_NAME = secrets["S3_BUCKET_NAME"]
SQS_QUEUE_NAME = secrets["SQS_Queue_Name"]
these variables are then used in different methods.
conftest.py
#pytest.fixture(scope='session', autouse=True)
def secret_manager_resource(aws_credentials):
"""Secret Manager mock client"""
with mock_secretsmanager():
conn = boto3.client("secretsmanager", region_name="us-east-1")
logger.info(f"Secret manager connection {conn}")
yield conn
test_file.py
#contextmanager
def secret_manager_setup(secret_manager_resource):
secret_manager_resource.create_secret(Name="test", SecretString="""{"S3_BUCKET_NAME": "test","SQS_Queue_Name": "test_queue"}""")
yield
class TestSecretManager:
def test_secret_manager(self, secret_manager_resource):
with secret_manager_setup(secret_manager_resource):
try:
result = secret_manager_resource.get_secret_value(SecretId="test")
json_result = json.loads(result['SecretString'])
assert json_result["S3_BUCKET_NAME"] == "test"
assert json_result["SQS_Queue_Name"] == "test_queue"
except Exception as err:
print("Error ---", err)
class TestClass:
def test_some_class(test_var):
from functions.something.some import something
something = someClass({}, param)
When I run pytest it directly goes inside TestClass and calls secret Manager and throws error as it is trying to connect to actual secret manager. Could someone suggest me what can be done to over come this issue?
TestClass is not mocked - so I wouldn't expect that to work. You could use Moto as a class-decorator to ensure everything inside someClass is mocked.
Note that the class-decorator creates a mock around test-methods only, so the code-under-test would have to be inside a test-method for this to work.
#mock_secretsmanager()
class TestClass:
def test_something():
from functions.something.some import something
something = someClass({}, param)
See http://docs.getmoto.org/en/latest/docs/getting_started.html#class-decorator for the documentation and more examples around this.

Python patch of a object creation not working

app.py
class UnderTest:
def one(self):
print('In one')
email = EmailSender(None, 'messwage');
email.send()
EmailSender.py
class EmailSender:
def __init__(self, config, message):
self.mess = message;
def send(self):
print("should not be invoked")
test_under_test.py
class test_under_test(TestCase):
#patch('EmailSender.EmailSender')
def test_one(self, email):
test = UnderTest()
email.send.return_value = None;
test.one();
The 'send' method of the EmailSender should not have invoked, but, it is being invoked. When i debug instead of the Mock object in the email variable in EmailSender.one method i see original object of EmailSender, the patch is not working as expected here. what should I do?

Groovy Binding: Cannot cast object with class 'custompackage.CustomClass' to class 'custompackage.CustomClass'

Using Groovy Binding to execute scripts from a main controller and attempting to pass a custom object, I get the error mentioned in the title.
Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'custompackage.CustomClass#60099951' with class 'custompackage.CustomClass' to class 'custompackage.CustomClass'
Here's the relevant code:
// Controller.groovy
import custompackage.CustomClass
CustomClass test = new CustomClass()
def binding = new Binding()
def engine = new GroovyScriptEngine('./src')
binding.setProperty("test", test)
engine.run("CustomScript.groovy", binding)
The file being run with above:
// CustomScript.groovy
import custompackage.CustomClass
CustomClass t
if(!binding.variables.containsKey("test")){
t = new CustomClass()
} else {
t = test
}
I'm defining the CustomClass t at the beginning for the purpose of autocomplete in my IDE. When running as def t it works fine.
I know the object is being passed correctly, due to the exception (and further printing of the object)
The error occurs on t = test
Why is Groovy trying to cast an object of the same type to it's type, and then failing to do so? And is there a fix that will still allow me to keep the statically typed t?
Thanks!
It seems custompackage.CustomClass in Controller.groovy is not the same as in CustomScript.groovy.
I checked the class instances in CustomScript.groovy with the debugger and found something interesting:
def a = CustomClass.class // Debugger: a={Class#1499} "class custompackage.CustomClass"
def b = test.class // Debugger: b={Class#1187} "class custompackage.CustomClass"
While when using GroovyShell instead of GroovyScriptEngine in Controller.groovy I get:
def a = CustomClass.class // Debugger: a={Class#1185} "class custompackage.CustomClass"
def b = test.class // Debugger: b={Class#1185} "class custompackage.CustomClass"
and the assignment t = test works without error.
The Controller.groovy file using GroovyShell looks like this:
// Controller.groovy
import custompackage.CustomClass
CustomClass test = new CustomClass()
def binding = new Binding()
def shell = new GroovyShell(binding)
binding.setProperty("test", test)
shell.evaluate(new File("CustomScript.groovy"))
I checked the documentation of GroovyScriptEngine and found a constructor which takes a ClassLoader as argument. Maybe that's the way to go but I don't know for sure.

Resources