@@ -302,7 +302,7 @@ async def test_{{ method.name|snake_case }}_async(transport: str = 'grpc_asyncio
302302def 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