summaryrefslogtreecommitdiffstats
path: root/Lib/unittest
diff options
context:
space:
mode:
authorChris Withers <chris@withers.org>2020-01-27 14:55:56 (GMT)
committerGitHub <noreply@github.com>2020-01-27 14:55:56 (GMT)
commita46575a8f2ded8b49e26c25bb67192e1500e76ca (patch)
tree4e6331742b11b7fbda4197118ec21793ae8dce11 /Lib/unittest
parentc7dd3c7d87d6961756d99b57aa13db7c7a03e1f8 (diff)
downloadcpython-a46575a8f2ded8b49e26c25bb67192e1500e76ca.zip
cpython-a46575a8f2ded8b49e26c25bb67192e1500e76ca.tar.gz
cpython-a46575a8f2ded8b49e26c25bb67192e1500e76ca.tar.bz2
Clarify and fix assertions that mocks have not been awaited (GH-18196)
- The gc.collect is needed for other implementations, such as pypy - Using context managers over multiple lines will only catch the warning from the first line in the context! - remove a skip for a test that no longer fails on pypy
Diffstat (limited to 'Lib/unittest')
-rw-r--r--Lib/unittest/test/testmock/testasync.py55
-rw-r--r--Lib/unittest/test/testmock/testmagicmethods.py2
2 files changed, 30 insertions, 27 deletions
diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py
index 6cba427..992076d 100644
--- a/Lib/unittest/test/testmock/testasync.py
+++ b/Lib/unittest/test/testmock/testasync.py
@@ -1,7 +1,9 @@
import asyncio
+import gc
import inspect
import re
import unittest
+from contextlib import contextmanager
from asyncio import run, iscoroutinefunction
from unittest import IsolatedAsyncioTestCase
@@ -52,6 +54,15 @@ async_foo_name = f'{__name__}.AsyncClass'
normal_foo_name = f'{__name__}.NormalClass'
+@contextmanager
+def assertNeverAwaited(test):
+ with test.assertWarnsRegex(RuntimeWarning, "was never awaited$"):
+ yield
+ # In non-CPython implementations of Python, this is needed because timely
+ # deallocation is not guaranteed by the garbage collector.
+ gc.collect()
+
+
class AsyncPatchDecoratorTest(unittest.TestCase):
def test_is_coroutine_function_patch(self):
@patch.object(AsyncClass, 'async_method')
@@ -284,8 +295,7 @@ class AsyncSpecTest(unittest.TestCase):
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
+ with assertNeverAwaited(self):
self.assertTrue(inspect.isawaitable(async_mock()))
sync_mock = mock_type(spec=normal_func)
@@ -299,8 +309,7 @@ class AsyncSpecTest(unittest.TestCase):
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
+ with assertNeverAwaited(self):
self.assertTrue(inspect.isawaitable(async_mock()))
sync_mock = mock_type(normal_func)
@@ -747,8 +756,7 @@ class AsyncMockAssert(unittest.TestCase):
def test_assert_called_but_not_awaited(self):
mock = AsyncMock(AsyncClass)
- with self.assertWarns(RuntimeWarning):
- # Will raise a warning because never awaited
+ with assertNeverAwaited(self):
mock.async_method()
self.assertTrue(iscoroutinefunction(mock.async_method))
mock.async_method.assert_called()
@@ -789,9 +797,9 @@ class AsyncMockAssert(unittest.TestCase):
def test_assert_called_twice_and_awaited_once(self):
mock = AsyncMock(AsyncClass)
coroutine = mock.async_method()
- with self.assertWarns(RuntimeWarning):
- # The first call will be awaited so no warning there
- # But this call will never get awaited, so it will warn here
+ # The first call will be awaited so no warning there
+ # But this call will never get awaited, so it will warn here
+ with assertNeverAwaited(self):
mock.async_method()
with self.assertRaises(AssertionError):
mock.async_method.assert_awaited()
@@ -826,38 +834,34 @@ class AsyncMockAssert(unittest.TestCase):
def test_assert_has_calls_not_awaits(self):
kalls = [call('foo')]
- with self.assertWarns(RuntimeWarning):
- # Will raise a warning because never awaited
+ with assertNeverAwaited(self):
self.mock('foo')
self.mock.assert_has_calls(kalls)
with self.assertRaises(AssertionError):
self.mock.assert_has_awaits(kalls)
def test_assert_has_mock_calls_on_async_mock_no_spec(self):
- with self.assertWarns(RuntimeWarning):
- # Will raise a warning because never awaited
+ with assertNeverAwaited(self):
self.mock()
kalls_empty = [('', (), {})]
self.assertEqual(self.mock.mock_calls, kalls_empty)
- with self.assertWarns(RuntimeWarning):
- # Will raise a warning because never awaited
+ with assertNeverAwaited(self):
self.mock('foo')
+ with assertNeverAwaited(self):
self.mock('baz')
mock_kalls = ([call(), call('foo'), call('baz')])
self.assertEqual(self.mock.mock_calls, mock_kalls)
def test_assert_has_mock_calls_on_async_mock_with_spec(self):
a_class_mock = AsyncMock(AsyncClass)
- with self.assertWarns(RuntimeWarning):
- # Will raise a warning because never awaited
+ with assertNeverAwaited(self):
a_class_mock.async_method()
kalls_empty = [('', (), {})]
self.assertEqual(a_class_mock.async_method.mock_calls, kalls_empty)
self.assertEqual(a_class_mock.mock_calls, [call.async_method()])
- with self.assertWarns(RuntimeWarning):
- # Will raise a warning because never awaited
+ with assertNeverAwaited(self):
a_class_mock.async_method(1, 2, 3, a=4, b=5)
method_kalls = [call(), call(1, 2, 3, a=4, b=5)]
mock_kalls = [call.async_method(), call.async_method(1, 2, 3, a=4, b=5)]
@@ -865,9 +869,9 @@ class AsyncMockAssert(unittest.TestCase):
self.assertEqual(a_class_mock.mock_calls, mock_kalls)
def test_async_method_calls_recorded(self):
- with self.assertWarns(RuntimeWarning):
- # Will raise warnings because never awaited
+ with assertNeverAwaited(self):
self.mock.something(3, fish=None)
+ with assertNeverAwaited(self):
self.mock.something_else.something(6, cake=sentinel.Cake)
self.assertEqual(self.mock.method_calls, [
@@ -889,19 +893,20 @@ class AsyncMockAssert(unittest.TestCase):
self.assertEqual(attr, [])
assert_attrs(self.mock)
- with self.assertWarns(RuntimeWarning):
- # Will raise warnings because never awaited
+ with assertNeverAwaited(self):
self.mock()
+ with assertNeverAwaited(self):
self.mock(1, 2)
+ with assertNeverAwaited(self):
self.mock(a=3)
self.mock.reset_mock()
assert_attrs(self.mock)
a_mock = AsyncMock(AsyncClass)
- with self.assertWarns(RuntimeWarning):
- # Will raise warnings because never awaited
+ with assertNeverAwaited(self):
a_mock.async_method()
+ with assertNeverAwaited(self):
a_mock.async_method(1, a=3)
a_mock.reset_mock()
diff --git a/Lib/unittest/test/testmock/testmagicmethods.py b/Lib/unittest/test/testmock/testmagicmethods.py
index 5690f7a..a4feae7 100644
--- a/Lib/unittest/test/testmock/testmagicmethods.py
+++ b/Lib/unittest/test/testmock/testmagicmethods.py
@@ -1,7 +1,6 @@
import math
import unittest
import os
-import sys
from asyncio import iscoroutinefunction
from unittest.mock import AsyncMock, Mock, MagicMock, _magics
@@ -429,7 +428,6 @@ class TestMockingMagicMethods(unittest.TestCase):
self.assertEqual(dir(mock), ['foo'])
- @unittest.skipIf('PyPy' in sys.version, "This fails differently on pypy")
def test_bound_methods(self):
m = Mock()