bpo-41877 Check for asert, aseert, assrt in mocks (GH-23165)
Currently, a Mock object which is not unsafe will raise an AttributeError if an attribute with the prefix assert or assret is accessed on it. This protects against misspellings of real assert method calls, which lead to tests passing silently even if the tested code does not satisfy the intended assertion. Recently a check was done in a large code base (Google) and three more frequent ways of misspelling assert were found causing harm: asert, aseert, assrt. These are now added to the existing check.
This commit is contained in:
parent
133aa2d581
commit
4662fa9bfe
|
@ -631,9 +631,9 @@ class NonCallableMock(Base):
|
||||||
elif _is_magic(name):
|
elif _is_magic(name):
|
||||||
raise AttributeError(name)
|
raise AttributeError(name)
|
||||||
if not self._mock_unsafe:
|
if not self._mock_unsafe:
|
||||||
if name.startswith(('assert', 'assret')):
|
if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')):
|
||||||
raise AttributeError("Attributes cannot start with 'assert' "
|
raise AttributeError("Attributes cannot start with 'assert' "
|
||||||
"or 'assret'")
|
"or its misspellings")
|
||||||
|
|
||||||
result = self._mock_children.get(name)
|
result = self._mock_children.get(name)
|
||||||
if result is _deleted:
|
if result is _deleted:
|
||||||
|
|
|
@ -1598,14 +1598,23 @@ class MockTest(unittest.TestCase):
|
||||||
#Issue21238
|
#Issue21238
|
||||||
def test_mock_unsafe(self):
|
def test_mock_unsafe(self):
|
||||||
m = Mock()
|
m = Mock()
|
||||||
msg = "Attributes cannot start with 'assert' or 'assret'"
|
msg = "Attributes cannot start with 'assert' or its misspellings"
|
||||||
with self.assertRaisesRegex(AttributeError, msg):
|
with self.assertRaisesRegex(AttributeError, msg):
|
||||||
m.assert_foo_call()
|
m.assert_foo_call()
|
||||||
with self.assertRaisesRegex(AttributeError, msg):
|
with self.assertRaisesRegex(AttributeError, msg):
|
||||||
m.assret_foo_call()
|
m.assret_foo_call()
|
||||||
|
with self.assertRaisesRegex(AttributeError, msg):
|
||||||
|
m.asert_foo_call()
|
||||||
|
with self.assertRaisesRegex(AttributeError, msg):
|
||||||
|
m.aseert_foo_call()
|
||||||
|
with self.assertRaisesRegex(AttributeError, msg):
|
||||||
|
m.assrt_foo_call()
|
||||||
m = Mock(unsafe=True)
|
m = Mock(unsafe=True)
|
||||||
m.assert_foo_call()
|
m.assert_foo_call()
|
||||||
m.assret_foo_call()
|
m.assret_foo_call()
|
||||||
|
m.asert_foo_call()
|
||||||
|
m.aseert_foo_call()
|
||||||
|
m.assrt_foo_call()
|
||||||
|
|
||||||
#Issue21262
|
#Issue21262
|
||||||
def test_assert_not_called(self):
|
def test_assert_not_called(self):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Mock objects which are not unsafe will now raise an AttributeError if an attribute with the prefix asert, aseert,
|
||||||
|
or assrt is accessed, in addition to this already happening for the prefixes assert or assret.
|
Loading…
Reference in New Issue