Python unittest patch mocking class property - python-3.x

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

Related

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

Access a variable from setup_method in pytest

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?

How to Mock a flask-restful class with kwargs

From Intermediate-Usage Flask-RESTful 0.3.7 documentation
in the Passing Constructor Parameters Into Resources section at the bottom, how would you write a test in order to mock kwargs? Side note: I tweaked it so the Smart Engine class is passed directly rather than being instantiated to a variable then passed.
from flask_restful import Resource
class TodoNext(Resource):
def __init__(self, **kwargs):
# smart_engine is a black box dependency
self.smart_engine = kwargs['smart_engine']
def get(self):
return self.smart_engine.next_todo()
You can inject the required dependency into TodoNext like so:
api.add_resource(TodoNext, '/next',
resource_class_kwargs={ 'smart_engine': SmartEngine() })
Test class in question:
import unittest
class TestTodoNext(unittest.TestCase):
todo_next_instance = TodoNext() # How would you mock smart_engine in this case?
You can use Mock object from unittest.mock to mock smart_engine.
import unittest
from unittest.mock import Mock
class TestTodoNext(unittest.TestCase):
smart_engine = Mock()
smart_engine.next_todo.return_value = "YOUR DESIRED RETURN VALUE"
todo_next_instance = TodoNext(smart_engine=smart_engine)
self.assertEqual(todo_next_instace.get(), "YOUR DESIRED RETURN VALUE")

Make method of derived class async

I have to create and use a class derived from an upstream package (not modifiable)
I want/need to add/modify a method in the derived class that should be async because i need to await a websocket send/recv in the method
I tried just to add async to the method but i get the message (from the base class method) that my method from derived class RuntimeWarning: coroutine MyCopyProgressHandler.end was never awaited
Is there a way to "convert" derived class method to async?
When you need to convert sync method to async you have several different options. Second one (run_in_executor) is probably the easiest one.
For example, this is how you can make sync function requests.get to run asynchronously:
import asyncio
import requests
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(10)
async def get(url):
loop = asyncio.get_running_loop()
response = await loop.run_in_executor(
executor,
requests.get,
url
)
return response.text
async def main():
res = await get('http://httpbin.org/get')
print(res)
asyncio.run(main())

How to mock "async with" statements?

I'm trying to write tests for a method that uses "async with" statements (in this case, aioredis's connection pool), i want to mock the connection to redis, but i'm having trouble figuring out how.
Here's what i have so far:
from asyncio import Future
from unittest.mock import MagicMock
import pytest
# The thing i'm trying to test
async def set_value(redis, value):
# Do things
async with redis.get() as conn:
await conn.set("key", value)
#My Mock classes
class MockRedis():
def get(self):
return MockAsyncPool()
class MockAsyncPool(MagicMock):
async def __aenter__(self):
conn = MagicMock()
f = Future()
f.set_result(True)
conn.set = MagicMock(return_value=f)
return conn
def __aexit__(self, exc_type, exc_val, exc_tb):
pass
# The actual test
#pytest.mark.asyncio
async def test_get_token():
redis = MockRedis()
token = await set_value(redis, 'something')
assert token is not None
I run it with:
py.test path/to/file.py
And i'm getting this error:
> await conn.set("key", value)
E TypeError: object NoneType can't be used in 'await' expression
__aexit__ needs to also be asyncronous (needs to return an awaitable):
async def __aexit__(self, exc_type, exc_val, exc_tb):
pass
Without being async it is returning None instead of a coroutine so it raises an error, as for the very misleading error message I have created this issue to point out that the error message could be greatly improved.

Resources