Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.

Commit 85e4d81

Browse files
committed
Push test coverage for AsyncClient to 100%
1 parent 0643c68 commit 85e4d81

1 file changed

Lines changed: 112 additions & 1 deletion

File tree

gapic/templates/tests/unit/%name_%version/%sub/test_%service.py.j2

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ async def test_{{ method.name|snake_case }}_async(transport: str = 'grpc_asyncio
302302
def test_{{ method.name|snake_case }}_field_headers():
303303
client = {{ service.client_name }}(
304304
credentials=credentials.AnonymousCredentials(),
305-
)
305+
)
306306

307307
# Any value that is part of the HTTP/1.1 URI should be sent as
308308
# a field header. Set these to a non-empty value.
@@ -333,6 +333,43 @@ def test_{{ method.name|snake_case }}_field_headers():
333333
{%- if not loop.last %}&{% endif -%}
334334
{%- endfor %}',
335335
) in kw['metadata']
336+
337+
338+
@pytest.mark.asyncio
339+
async def test_{{ method.name|snake_case }}_field_headers_async():
340+
client = {{ service.async_client_name }}(
341+
credentials=credentials.AnonymousCredentials(),
342+
)
343+
344+
# Any value that is part of the HTTP/1.1 URI should be sent as
345+
# a field header. Set these to a non-empty value.
346+
request = {{ method.input.ident }}(
347+
{%- for field_header in method.field_headers %}
348+
{{ field_header }}='{{ field_header }}/value',
349+
{%- endfor %}
350+
)
351+
352+
# Mock the actual call within the gRPC stub, and fake the request.
353+
with mock.patch.object(
354+
type(client._client._transport.{{ method.name|snake_case }}),
355+
'__call__') as call:
356+
call.return_value = grpc_helpers_async.FakeUnaryUnaryCall({{ method.output.ident }}())
357+
await client.{{ method.name|snake_case }}(request)
358+
359+
# Establish that the underlying gRPC stub method was called.
360+
assert len(call.mock_calls) == 1
361+
_, args, _ = call.mock_calls[0]
362+
assert args[0] == request
363+
364+
# Establish that the field header was sent.
365+
_, _, kw = call.mock_calls[0]
366+
assert (
367+
'x-goog-request-params',
368+
'{% for field_header in method.field_headers -%}
369+
{{ field_header }}={{ field_header }}/value
370+
{%- if not loop.last %}&{% endif -%}
371+
{%- endfor %}',
372+
) in kw['metadata']
336373
{% endif %}
337374

338375
{% if method.ident.package != method.input.ident.package %}
@@ -415,6 +452,80 @@ def test_{{ method.name|snake_case }}_flattened_error():
415452
{{ field.name }}={{ field.mock_value }},
416453
{%- endfor %}
417454
)
455+
456+
457+
@pytest.mark.asyncio
458+
async def test_{{ method.name|snake_case }}_flattened_async():
459+
client = {{ service.async_client_name }}(
460+
credentials=credentials.AnonymousCredentials(),
461+
)
462+
463+
# Mock the actual call within the gRPC stub, and fake the request.
464+
with mock.patch.object(
465+
type(client._client._transport.{{ method.name|snake_case }}),
466+
'__call__') as call:
467+
# Designate an appropriate return value for the call.
468+
{% if method.void -%}
469+
call.return_value = None
470+
{% elif method.lro -%}
471+
call.return_value = operations_pb2.Operation(name='operations/op')
472+
{% elif method.server_streaming -%}
473+
call.return_value = iter([{{ method.output.ident }}()])
474+
{% else -%}
475+
call.return_value = {{ method.output.ident }}()
476+
{% endif %}
477+
478+
479+
{% if method.void -%}
480+
call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
481+
{% elif method.lro -%}
482+
call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
483+
operations_pb2.Operation(name='operations/spam')
484+
)
485+
{% elif not method.client_streaming and method.server_streaming -%}
486+
call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True)
487+
{% elif method.client_streaming and method.server_streaming -%}
488+
call.return_value = mock.Mock(aio.StreamStreamCall, autospec=True)
489+
{% else -%}
490+
call.return_value ={{' '}}
491+
{%- if not method.client_streaming and not method.server_streaming -%}
492+
grpc_helpers_async.FakeUnaryUnaryCall
493+
{%- else -%}
494+
grpc_helpers_async.FakeStreamUnaryCall
495+
{%- endif -%}({{ method.output.ident }}())
496+
{% endif -%}
497+
# Call the method with a truthy value for each flattened field,
498+
# using the keyword arguments to the method.
499+
response = await client.{{ method.name|snake_case }}(
500+
{%- for field in method.flattened_fields.values() %}
501+
{{ field.name }}={{ field.mock_value }},
502+
{%- endfor %}
503+
)
504+
505+
# Establish that the underlying call was made with the expected
506+
# request object values.
507+
assert len(call.mock_calls) == 1
508+
_, args, _ = call.mock_calls[0]
509+
{% for key, field in method.flattened_fields.items() -%}
510+
assert args[0].{{ key }} == {{ field.mock_value }}
511+
{% endfor %}
512+
513+
514+
@pytest.mark.asyncio
515+
async def test_{{ method.name|snake_case }}_flattened_error_async():
516+
client = {{ service.async_client_name }}(
517+
credentials=credentials.AnonymousCredentials(),
518+
)
519+
520+
# Attempting to call a method with both a request object and flattened
521+
# fields is an error.
522+
with pytest.raises(ValueError):
523+
await client.{{ method.name|snake_case }}(
524+
{{ method.input.ident }}(),
525+
{%- for field in method.flattened_fields.values() %}
526+
{{ field.name }}={{ field.mock_value }},
527+
{%- endfor %}
528+
)
418529
{% endif %}
419530

420531

0 commit comments

Comments
 (0)