diff options
author | Lisa Roach <lisaroach14@gmail.com> | 2019-09-30 04:56:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-30 04:56:47 (GMT) |
commit | 3667e1ee6c90e6d3b6a745cd590ece87118f81ad (patch) | |
tree | d9802110a2f6ebbd181b904b05956a56d88c8c44 /Lib | |
parent | 5bcc6d89bcb622a6786fff632fabdcaf67dbb4e2 (diff) | |
download | cpython-3667e1ee6c90e6d3b6a745cd590ece87118f81ad.zip cpython-3667e1ee6c90e6d3b6a745cd590ece87118f81ad.tar.gz cpython-3667e1ee6c90e6d3b6a745cd590ece87118f81ad.tar.bz2 |
bpo-38163: Child mocks detect their type as sync or async (GH-16471)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/unittest/mock.py | 5 | ||||
-rw-r--r-- | Lib/unittest/test/testmock/testasync.py | 67 |
2 files changed, 45 insertions, 27 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index e797d2f..a48132c 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -992,8 +992,9 @@ class NonCallableMock(Base): # Any asynchronous magic becomes an AsyncMock klass = AsyncMock elif issubclass(_type, AsyncMockMixin): - if _new_name in _all_sync_magics: - # Any synchronous magic becomes a MagicMock + if (_new_name in _all_sync_magics or + self._mock_methods and _new_name in self._mock_methods): + # Any synchronous method on AsyncMock becomes a MagicMock klass = MagicMock else: klass = AsyncMock diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py index 5a9e93e..6b2d49d 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/unittest/test/testmock/testasync.py @@ -3,7 +3,7 @@ import inspect import re import unittest -from unittest.mock import (ANY, call, AsyncMock, patch, MagicMock, +from unittest.mock import (ANY, call, AsyncMock, patch, MagicMock, Mock, create_autospec, sentinel, _CallList) @@ -232,33 +232,50 @@ class AsyncAutospecTest(unittest.TestCase): class AsyncSpecTest(unittest.TestCase): - def test_spec_as_async_positional_magicmock(self): - mock = MagicMock(async_func) - self.assertIsInstance(mock, MagicMock) - m = mock() - self.assertTrue(inspect.isawaitable(m)) - asyncio.run(m) + def test_spec_normal_methods_on_class(self): + def inner_test(mock_type): + mock = mock_type(AsyncClass) + self.assertIsInstance(mock.async_method, AsyncMock) + self.assertIsInstance(mock.normal_method, MagicMock) - def test_spec_as_async_kw_magicmock(self): - mock = MagicMock(spec=async_func) - self.assertIsInstance(mock, MagicMock) - m = mock() - self.assertTrue(inspect.isawaitable(m)) - asyncio.run(m) + for mock_type in [AsyncMock, MagicMock]: + with self.subTest(f"test method types with {mock_type}"): + inner_test(mock_type) - def test_spec_as_async_kw_AsyncMock(self): - mock = AsyncMock(spec=async_func) - self.assertIsInstance(mock, AsyncMock) - m = mock() - self.assertTrue(inspect.isawaitable(m)) - asyncio.run(m) + def test_spec_normal_methods_on_class_with_mock(self): + mock = Mock(AsyncClass) + self.assertIsInstance(mock.async_method, AsyncMock) + self.assertIsInstance(mock.normal_method, Mock) - def test_spec_as_async_positional_AsyncMock(self): - mock = AsyncMock(async_func) - self.assertIsInstance(mock, AsyncMock) - m = mock() - self.assertTrue(inspect.isawaitable(m)) - asyncio.run(m) + def test_spec_mock_type_kw(self): + def inner_test(mock_type): + async_mock = mock_type(spec=async_func) + self.assertIsInstance(async_mock, mock_type) + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + self.assertTrue(inspect.isawaitable(async_mock())) + + sync_mock = mock_type(spec=normal_func) + self.assertIsInstance(sync_mock, mock_type) + + for mock_type in [AsyncMock, MagicMock, Mock]: + with self.subTest(f"test spec kwarg with {mock_type}"): + inner_test(mock_type) + + def test_spec_mock_type_positional(self): + def inner_test(mock_type): + async_mock = mock_type(async_func) + self.assertIsInstance(async_mock, mock_type) + with self.assertWarns(RuntimeWarning): + # Will raise a warning because never awaited + self.assertTrue(inspect.isawaitable(async_mock())) + + sync_mock = mock_type(normal_func) + self.assertIsInstance(sync_mock, mock_type) + + for mock_type in [AsyncMock, MagicMock, Mock]: + with self.subTest(f"test spec positional with {mock_type}"): + inner_test(mock_type) def test_spec_as_normal_kw_AsyncMock(self): mock = AsyncMock(spec=normal_func) |