Skip to content

Commit 2329586

Browse files
committed
test: generate bound model methods tests
1 parent cdcde82 commit 2329586

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

tests/unit/conftest.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from __future__ import annotations
44

5+
import inspect
6+
from typing import Callable, ClassVar
57
from unittest import mock
68

79
import pytest
@@ -130,3 +132,80 @@ def action_list_response(action1_running, action2_running):
130132
action2_running,
131133
],
132134
}
135+
136+
137+
def build_kwargs_mock(func: Callable) -> dict[str, mock.Mock]:
138+
"""
139+
Generate a kwargs dict that may be passed to the provided function for testing purposes.
140+
"""
141+
s = inspect.signature(func)
142+
143+
kwargs = {}
144+
for name, param in s.parameters.items():
145+
if name in ("self",):
146+
continue
147+
148+
if param.kind in (param.POSITIONAL_OR_KEYWORD, param.KEYWORD_ONLY):
149+
kwargs[name] = mock.Mock()
150+
continue
151+
152+
raise NotImplementedError(f"unsupported parameter kind: {param.kind}")
153+
154+
return kwargs
155+
156+
157+
def pytest_generate_tests(metafunc: pytest.Metafunc):
158+
"""
159+
Magic function to generate a test for each bound model method.
160+
"""
161+
if "bound_model_method" in metafunc.fixturenames:
162+
metafunc.parametrize("bound_model_method", metafunc.cls.methods)
163+
164+
165+
class BoundModelTestCase:
166+
methods: ClassVar[list[Callable]]
167+
168+
def test_method_list(self, bound_model):
169+
"""
170+
Ensure the list of bound model methods is up to date.
171+
"""
172+
members_count = 0
173+
for name, member in inspect.getmembers(
174+
bound_model,
175+
lambda m: inspect.ismethod(m)
176+
and m.__func__ in bound_model.__class__.__dict__.values(),
177+
):
178+
# Actions methods are already tested in TestBoundModelActions.
179+
if name in ("__init__", "get_actions", "get_actions_list"):
180+
continue
181+
182+
assert member.__func__ in self.__class__.methods
183+
members_count += 1
184+
185+
assert members_count == len(self.__class__.methods)
186+
187+
def test_method(
188+
self,
189+
resource_client,
190+
bound_model,
191+
bound_model_method: Callable,
192+
):
193+
# Check if the resource client has a method named after the bound model method.
194+
assert hasattr(resource_client, bound_model_method.__name__)
195+
196+
# Mock the resource client method.
197+
resource_client_method_mock = mock.MagicMock()
198+
setattr(
199+
resource_client,
200+
bound_model_method.__name__,
201+
resource_client_method_mock,
202+
)
203+
204+
kwargs = build_kwargs_mock(bound_model_method)
205+
206+
# Call the bound model method
207+
result = getattr(bound_model, bound_model_method.__name__)(**kwargs)
208+
209+
resource_client_method_mock.assert_called_with(bound_model, **kwargs)
210+
211+
assert result is resource_client_method_mock.return_value

0 commit comments

Comments
 (0)