gh-124176: Add special support for dataclasses to create_autospec (#124429)

This commit is contained in:
sobolevn 2024-09-27 09:48:31 +03:00 committed by GitHub
parent 08e1bbe4a3
commit 3a0e7f5762
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 92 additions and 6 deletions

View file

@ -8,8 +8,10 @@ from unittest.mock import (
Mock, ANY, _CallList, patch, PropertyMock, _callable
)
from dataclasses import dataclass, field, InitVar
from datetime import datetime
from functools import partial
from typing import ClassVar
class SomeClass(object):
def one(self, a, b): pass
@ -1034,6 +1036,76 @@ class SpecSignatureTest(unittest.TestCase):
self.assertEqual(mock.mock_calls, [])
self.assertEqual(rv.mock_calls, [])
def test_dataclass_post_init(self):
@dataclass
class WithPostInit:
a: int = field(init=False)
b: int = field(init=False)
def __post_init__(self):
self.a = 1
self.b = 2
for mock in [
create_autospec(WithPostInit, instance=True),
create_autospec(WithPostInit()),
]:
with self.subTest(mock=mock):
self.assertIsInstance(mock.a, int)
self.assertIsInstance(mock.b, int)
# Classes do not have these fields:
mock = create_autospec(WithPostInit)
msg = "Mock object has no attribute"
with self.assertRaisesRegex(AttributeError, msg):
mock.a
with self.assertRaisesRegex(AttributeError, msg):
mock.b
def test_dataclass_default(self):
@dataclass
class WithDefault:
a: int
b: int = 0
for mock in [
create_autospec(WithDefault, instance=True),
create_autospec(WithDefault(1)),
]:
with self.subTest(mock=mock):
self.assertIsInstance(mock.a, int)
self.assertIsInstance(mock.b, int)
def test_dataclass_with_method(self):
@dataclass
class WithMethod:
a: int
def b(self) -> int:
return 1
for mock in [
create_autospec(WithMethod, instance=True),
create_autospec(WithMethod(1)),
]:
with self.subTest(mock=mock):
self.assertIsInstance(mock.a, int)
mock.b.assert_not_called()
def test_dataclass_with_non_fields(self):
@dataclass
class WithNonFields:
a: ClassVar[int]
b: InitVar[int]
msg = "Mock object has no attribute"
for mock in [
create_autospec(WithNonFields, instance=True),
create_autospec(WithNonFields(1)),
]:
with self.subTest(mock=mock):
with self.assertRaisesRegex(AttributeError, msg):
mock.a
with self.assertRaisesRegex(AttributeError, msg):
mock.b
class TestCallList(unittest.TestCase):