I am fixing an old test, that extensively uses mocks, and I encountered challenges setting them up. I have a peace of code that looks like this:
content = await page.content()
links = await page.locator("a").all()
It’s been a while since I used Python daily, and I don’t know how to correctly set the mock for page
from the example. The content
is an async method, and the locator
is not.
Environment:
Base
Platform: darwin
OS: posix
Python: 3.11.9
Path: /nix/store/7rr2jhwcm4z0r727q4lpfkbvfmjcg07k-python3-3.11.9
Executable: /nix/store/7rr2jhwcm4z0r727q4lpfkbvfmjcg07k-python3-3.11.9/bin/python3.11
pytest 7.4.3 pytest: simple powerful testing with Python
pytest-asyncio 0.21.1 Pytest support for asyncio
I went through the docs, and couldn’t find an answer. After some jumping between TypeError: object MagicMock can't be used in 'await' expression
and AttributeError: 'coroutine' object has no attribute 'all'
I came up with this snippet:
from unittest.mock import AsyncMock
@pytest.mark.asyncio
async def test_async_mocks():
locator = AsyncMock()
page = AsyncMock()
locator.all = AsyncMock(return_value="Hello, there")
page.content = AsyncMock(return_value="Hello")
page.locator = lambda *args: locator
assert "Hello" == await page.content()
assert "Hello, there" == await page.locator("a").all()
The lambda
looks like a hack, since I haven’t seen any examples similar to this in the documentation. How can I set up this mock with mock API?