151 def __call__(self, servicer_method, /) -> MockDecorator:
153 Returns a decorator to mock the specified gRPC service method implementation.
157 @snippet samples/grpc_service/testsuite/test_grpc.py Prepare modules
158 @snippet samples/grpc_service/testsuite/test_grpc.py grpc client test
160 servicer_class = _get_class_from_method(servicer_method)
162 return mock.install_handler(servicer_method.__name__)
164 def mock_factory(self, servicer_class, /) -> Callable[[str], MockDecorator]:
166 Allows to create a fixture as a shorthand for mocking methods of the specified gRPC service.
170 @snippet grpc/functional_tests/metrics/tests/conftest.py Prepare modules
171 @snippet grpc/functional_tests/metrics/tests/conftest.py Prepare server mock
172 @snippet grpc/functional_tests/metrics/tests/test_metrics.py grpc client test
175 def factory(method_name):
176 method = getattr(servicer_class, method_name,
None)
178 raise ValueError(f
'No method "{method_name}" in servicer class "{servicer_class.__name__}"')
181 _check_is_servicer_class(servicer_class)
186 Installs as a mock `servicer`, the class of which should inherit from a generated `*Servicer` class.
188 1. Write a service implementation:
190 @snippet grpc/functional_tests/middleware_client/tests/test_install_servicer.py servicer
192 @note Inheritance from multiple `*Servicer` classes at once is allowed.
194 2. Install servicer instance:
196 @snippet grpc/functional_tests/middleware_client/tests/test_install_servicer.py install servicer
200 @snippet grpc/functional_tests/middleware_client/tests/test_install_servicer.py use mock
202 base_servicer_classes = [cls
for cls
in inspect.getmro(type(servicer))
if _is_servicer_class(cls)]
203 if not base_servicer_classes:
204 raise ValueError(f
"Given object's type ({type(servicer)}) is not inherited from any grpc *Servicer class")
205 proxy = _MockProxy(servicer)
206 for servicer_class
in base_servicer_classes:
209 for python_method_name
in mock.known_methods:
210 if _get_class_that_defined_method(type(servicer), python_method_name)
not in base_servicer_classes:
211 handler_func: types.MethodType = getattr(servicer, python_method_name)
212 callqueue = mock.install_handler(python_method_name)(handler_func)
213 object.__setattr__(proxy, python_method_name, callqueue)
214 return typing.cast(Servicer, proxy)
220async def _stop_server(server: grpc.aio.Server, /) ->
None:
221 async def stop_server():
222 await server.stop(grace=
None)
223 await server.wait_for_termination()
225 stop_server_task = asyncio.shield(asyncio.create_task(stop_server()))
229 await stop_server_task
230 except asyncio.CancelledError:
231 await stop_server_task
236def _get_class_from_method(method) -> type:
238 assert inspect.isfunction(method), f
'Expected an unbound method: foo(ClassName.MethodName), got: {method}'
239 class_name = method.__qualname__.split(
'.<locals>', 1)[0].rsplit(
'.', 1)[0]
241 cls = getattr(inspect.getmodule(method), class_name)
242 except AttributeError:
243 cls = method.__globals__.get(class_name)
244 assert isinstance(cls, type)
248def _get_class_that_defined_method(cls: type, method_name: str) -> type |
None:
249 for cls
in inspect.getmro(cls):
250 if method_name
in cls.__dict__:
256def _is_servicer_class(cls: type) -> bool:
258 return '_pb2_grpc.' in inspect.getfile(cls)
263class _MockProxy(Generic[Servicer]):
264 def __init__(self, wrapped_servicer: Servicer) ->
None:
265 object.__setattr__(self,
'_wrapped_servicer', wrapped_servicer)
267 def __getattr__(self, name: str) -> Any:
268 servicer: Servicer = object.__getattribute__(self,
'_wrapped_servicer')
269 return getattr(servicer, name)
271 def __setattr__(self, name: str, value: Any) ->
None:
272 servicer: Servicer = object.__getattribute__(self,
'_wrapped_servicer')
273 setattr(servicer, name, value)