question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Error in 'async with' statement when mocking coroutine that returns MagicMock

See original GitHub issue
import pytest
import asyncio
from asynctest import MagicMock, CoroutineMock

class TestClass(object):
    @pytest.mark.asyncio
    async def test_get_queue_url(self):
        test_client = MagicMock()
        test_session = MagicMock()
        expected = "testvalue"

        test_client.get_test = CoroutineMock(side_effect=[expected])
        test_session.create_client = CoroutineMock(side_effect=[test_client])
        async with test_session.create_client("something") as client:
            print("hello")

For some reason, this generates the following error:

self = <test_Distributor.TestClass object at 0x00000242FDA174A8>

	@pytest.mark.asyncio
	async def test_get_queue_url(self):
		test_client = MagicMock()
		test_session = MagicMock()
		expected = "testvalue"

		test_client.get_test = CoroutineMock(side_effect=[expected])
		test_session.create_client = CoroutineMock(side_effect=[test_client])
>       async with test_session.create_client("something") as client:
E       AttributeError: __aexit__

Is this expected? I would’ve thought that the coroutine gets called and returns the MagicMock, which should be able to be used in the async with statement. Unless I’m doing something wrong, maybe someone can point me in the right direction.

Thanks!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
Martiuswebcommented, Jun 19, 2018

I think you misunderstood my comment because of the bad formatting.

When python executes

with A as B:
    pass

the interpreter calls A.aenter (a coroutine) and the result of this call is assigned to the symbol B. In you case A is test_session.create_client(), which means that the method aenter is called on the object returned by the call to test_session.create_client, not on the create_client mock itself.

this means that you need to do something like:

mock_client = MagicMock()
mock_client.get_test = CoroutineMock(return_value=expected)

context_manager = MagicMock()
context_manager.__aenter__.return_value = mock_client

mock_session = MagicMock()
mock_session.create_client.return_value = context_manager
2reactions
Martiuswebcommented, Jun 19, 2018

@Kentzo is correct but missing a small thing:

__aenter__ is called on the result of create_client(), not create_client itself, you need to do something like:

test_session.create_client().__aenter__.get_test = CoroutineMock(side_effect=[expected])

This is true as long as the create_client mock returns the same object.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to mock asyncio coroutines? - python - Stack Overflow
i.e. read() is a coroutine and you want to first return some data b'data' , and then return an EOF-like condition (e.g. no...
Read more >
Mocking — asynctest 0.12.3 documentation
A CoroutineMock object is not awaitable, but it returns a coroutine instance when called. All the features of asynctest.
Read more >
AsyncMock issue with awaitable return_value/side_effect/wraps
msg357000 ‑ (view) Author: Jason Fried (fried) * Date: 2019‑11‑19 23:04 msg357116 ‑ (view) Author: Lisa Roach (lisroach) * Date: 2019‑11‑21 00:27 msg357190 ‑ (view)...
Read more >
Strategies for Testing Async Code in Python - Agari
However, you cannot mock a coroutine with the stdlib unittest.mock framework ... we can use AsyncContextManager in any async with statement.
Read more >
Strategies for Testing Async Code in Python | by Agari | Medium
However, you cannot mock a coroutine with the stdlib unittest.mock framework ... we can use AsyncContextManager in any async with statement.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found