3

I have been working on fastAPI and have some async methods to generate an auth token

Writting the unit testing I'm getting the following error:

TypeError: test_get_auth_token() missing 2 required positional arguments: 'test_input' and 'expected_result'

my unit test looks like:

class TestGenerateAuthToken(IsolatedAsyncioTestCase):
    """
    """
    
    @pytest.mark.parametrize(
        "test_input,expected_result",
        [("user", "user_token"), ("admin", "admin_token")],
    )
    @mock.patch("myaauth.get_token", new_callable=AsyncMock)
    async def test_get_auth_token(self, get_token_mock, test_input, expected_result):
        """
        Test get_auth_header
        """
        def mock_generate_user_token(_type):
            return f"{_type}_token"

        get_token_mock.side_effect = mock_generate_user_token
        assert await myaauth.get_token(test_input) == expected_result

I know is as simple as to just remove the parametrize, but I wanna know if is possible to do so

  • 1
    Does this answer your question? [Py.test: parametrize test cases from classes](https://stackoverflow.com/q/35561843/8601760) – aaron Nov 17 '22 at 15:21
  • ^ Specifically that answer might be worth a try https://stackoverflow.com/a/67462680/674039 , it alleges to be a drop-in replacement for `pytest.mark.parametrize`. Careful with the spelling, `parametrize` and `parameterize` are different PyPI projects. – wim Nov 17 '22 at 23:19
  • [Pytest docs state it pretty clear](https://docs.pytest.org/en/7.1.x/how-to/unittest.html#pytest-features-in-unittest-testcase-subclasses): _The following pytest features do not work, and probably never will due to different design philosophies: Fixtures (except for autouse fixtures, see below); Parametrization; Custom hooks._ So the answer is no, it is not possible to use `pytest.mark.parameterize` in unittest-style tests. – hoefling Nov 23 '22 at 17:09

1 Answers1

-1

It is not related to mock.

The reason is that pytest.mark.parametrize is not compatible with unittest.IsolatedAsyncioTestCase.

Instead, you could try using pytest's plugin, for example, pytest-asyncio, to let pytest work with the coroutine test function.

from unittest import mock
from unittest.mock import AsyncMock

import pytest as pytest

import myaauth


class TestGenerateAuthToken:
    @pytest.mark.parametrize(
        "test_input,expected_result",
        [("user", "user_token"), ("admin", "admin_token")],
    )
    @pytest.mark.asyncio
    @mock.patch("myaauth.get_token", new_callable=AsyncMock)
    async def test_get_auth_token(self, get_token_mock, test_input, expected_result):
        """
        Test get_auth_header
        """

        def mock_generate_user_token(_type):
            return f"{_type}_token"

        get_token_mock.side_effect = mock_generate_user_token
        assert await myaauth.get_token(test_input) == expected_result
-> % python -m pytest pytest_coroutine.py
=================================================================================================== test session starts ===================================================================================================
platform darwin -- Python 3.10.8, pytest-7.2.0, pluggy-1.0.0
rootdir: /Users/james/PycharmProjects/stackoverflow
plugins: asyncio-0.20.2
asyncio: mode=strict
collected 2 items                                                                                                                                                                                                         

pytest_coroutine.py ..                                                                                                                                                                                                  [100%]

==================================================================================================== 2 passed in 0.03s ====================================================================================================
James Lan
  • 248
  • 2
  • 8
  • Do you have a reference for that _"`pytest` is not compatible with `unittest.IsolatedAsyncioTestCase`"_? https://github.com/pytest-dev/pytest/pull/6927 seems to suggest it should be fine. – wim Nov 17 '22 at 02:16
  • pytest is compatible with `IsolatedAsyncioTestCase`. As in, it is able to find and run tests using `IsolatedAsyncioTestCase`. – Gabriel Cappelli Nov 17 '22 at 12:07
  • Now, it seems some features of pytest do not work when doing this, in this instance the parametrize function, which is what OP and I are insterested in. – Gabriel Cappelli Nov 17 '22 at 12:08
  • @wim @gabriel-cappelli Thanks for pointing out that `pytest` has some compatibility with `unittest.IsolatedAsyncioTestCase`, that it could discover and run the test. Updated the answer more accurate that `pytest.mark.parametrize` doesn't work with it. – James Lan Nov 17 '22 at 22:45
  • 2
    I think the question is basically a dupe of [_Does pytest parametrized test work with unittest class based tests?_](https://stackoverflow.com/q/18182251/674039). I am not the downvoter. – wim Nov 17 '22 at 23:07