summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorLisa Roach <lisaroach14@gmail.com>2019-09-30 04:56:47 (GMT)
committerGitHub <noreply@github.com>2019-09-30 04:56:47 (GMT)
commit3667e1ee6c90e6d3b6a745cd590ece87118f81ad (patch)
treed9802110a2f6ebbd181b904b05956a56d88c8c44 /Lib
parent5bcc6d89bcb622a6786fff632fabdcaf67dbb4e2 (diff)
downloadcpython-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.py5
-rw-r--r--Lib/unittest/test/testmock/testasync.py67
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)