Skip to content

Commit c440807

Browse files
authored
cleanup: refactor empty call test macro (#2110)
1 parent 28d3ed5 commit c440807

File tree

8 files changed

+268
-182
lines changed

8 files changed

+268
-182
lines changed

gapic/templates/tests/unit/gapic/%name_%version/%sub/test_macros.j2

Lines changed: 72 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -123,37 +123,7 @@ def test_{{ method_name }}(request_type, transport: str = 'grpc'):
123123

124124

125125
{% if not method.client_streaming %}
126-
def test_{{ method_name }}_empty_call():
127-
# This test is a coverage failsafe to make sure that totally empty calls,
128-
# i.e. request == None and no flattened fields passed, work.
129-
client = {{ service.client_name }}(
130-
credentials=ga_credentials.AnonymousCredentials(),
131-
transport='grpc',
132-
)
133-
134-
# Mock the actual call within the gRPC stub, and fake the request.
135-
with mock.patch.object(
136-
type(client.transport.{{ method.transport_safe_name|snake_case }}),
137-
'__call__') as call:
138-
call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string.
139-
client.{{ method_name }}()
140-
call.assert_called()
141-
_, args, _ = call.mock_calls[0]
142-
{% if method.client_streaming %}
143-
assert next(args[0]) == request
144-
{% else %}
145-
{% with method_settings = api.all_method_settings.get(method.meta.address.proto) %}
146-
{% if method_settings is not none %}
147-
{% for auto_populated_field in method_settings.auto_populated_fields %}
148-
# Ensure that the uuid4 field is set according to AIP 4235
149-
assert re.match(r"{{ uuid4_re }}", args[0].{{ auto_populated_field }})
150-
# clear UUID field so that the check below succeeds
151-
args[0].{{ auto_populated_field }} = None
152-
{% endfor %}
153-
{% endif %}{# if method_settings is not none #}
154-
{% endwith %}{# method_settings #}
155-
assert args[0] == {{ method.input.ident }}()
156-
{% endif %}
126+
{{ empty_call_test(method, method_name, service, api, uuid4_re)}}
157127

158128

159129
def test_{{ method_name }}_non_empty_request_with_auto_populated_field():
@@ -249,59 +219,7 @@ def test_{{ method_name }}_use_cached_wrapped_rpc():
249219

250220
{% if not full_extended_lro %}
251221
{% if not method.client_streaming %}
252-
@pytest.mark.asyncio
253-
async def test_{{ method_name }}_empty_call_async():
254-
# This test is a coverage failsafe to make sure that totally empty calls,
255-
# i.e. request == None and no flattened fields passed, work.
256-
client = {{ service.async_client_name }}(
257-
credentials=async_anonymous_credentials(),
258-
transport='grpc_asyncio',
259-
)
260-
261-
# Mock the actual call within the gRPC stub, and fake the request.
262-
with mock.patch.object(
263-
type(client.transport.{{ method.transport_safe_name|snake_case }}),
264-
'__call__') as call:
265-
# Designate an appropriate return value for the call.
266-
{% if method.void %}
267-
call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
268-
{% elif method.lro %}
269-
call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
270-
operations_pb2.Operation(name='operations/spam')
271-
)
272-
{% elif not method.client_streaming and method.server_streaming %}
273-
call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True)
274-
call.return_value.read = mock.AsyncMock(side_effect=[{{ method.output.ident }}()])
275-
{% elif method.client_streaming and method.server_streaming %}
276-
call.return_value = mock.Mock(aio.StreamStreamCall, autospec=True)
277-
call.return_value.read = mock.AsyncMock(side_effect=[{{ method.output.ident }}()])
278-
{% else %}
279-
call.return_value = {{ '' }}
280-
{%- if not method.client_streaming and not method.server_streaming -%}
281-
grpc_helpers_async.FakeUnaryUnaryCall
282-
{%- else -%}
283-
grpc_helpers_async.FakeStreamUnaryCall
284-
{%- endif -%}({{ method.output.ident }}(
285-
{% for field in method.output.fields.values() | rejectattr('message') %}{% if not field.oneof or field.proto3_optional %}
286-
{{ field.name }}={{ field.mock_value }},
287-
{% endif %}
288-
{% endfor %}
289-
))
290-
{% endif %}
291-
response = await client.{{ method_name }}()
292-
call.assert_called()
293-
_, args, _ = call.mock_calls[0]
294-
{% with method_settings = api.all_method_settings.get(method.meta.address.proto) %}
295-
{% if method_settings is not none %}
296-
{% for auto_populated_field in method_settings.auto_populated_fields %}
297-
# Ensure that the uuid4 field is set according to AIP 4235
298-
assert re.match(r"{{ uuid4_re }}", args[0].{{ auto_populated_field }})
299-
# clear UUID field so that the check below succeeds
300-
args[0].{{ auto_populated_field }} = None
301-
{% endfor %}
302-
{% endif %}{# if method_settings is not none #}
303-
{% endwith %}{# method_settings #}
304-
assert args[0] == {{ method.input.ident }}()
222+
{{ empty_call_test(method, method_name, service, api, uuid4_re, is_async=True) }}
305223
{% endif %}
306224

307225
@pytest.mark.asyncio
@@ -1888,3 +1806,73 @@ def test_{{ method_name }}_rest_no_http_options():
18881806
{% endif %}{# not method.http_options #}
18891807
{% endwith %}{# method_name #}
18901808
{% endmacro %}
1809+
1810+
1811+
{% macro empty_call_test(method, method_name, service, api, uuid4_re, is_async=False) %}
1812+
{% if is_async %}
1813+
@pytest.mark.asyncio
1814+
async def test_{{ method_name }}_empty_call_async():
1815+
{% else %}
1816+
def test_{{ method_name }}_empty_call():
1817+
{% endif %}{# if is_async #}
1818+
# This test is a coverage failsafe to make sure that totally empty calls,
1819+
# i.e. request == None and no flattened fields passed, work.
1820+
{% if is_async %}
1821+
client = {{ service.async_client_name }}(
1822+
credentials=async_anonymous_credentials(),
1823+
transport='grpc_asyncio',
1824+
)
1825+
{% else %}
1826+
client = {{ service.client_name }}(
1827+
credentials=ga_credentials.AnonymousCredentials(),
1828+
transport='grpc',
1829+
)
1830+
{% endif %}{# if is_async #}
1831+
1832+
# Mock the actual call within the gRPC stub, and fake the request.
1833+
with mock.patch.object(
1834+
type(client.transport.{{ method.transport_safe_name|snake_case }}),
1835+
'__call__') as call:
1836+
{% if is_async %}
1837+
# Designate an appropriate return value for the call.
1838+
{% if method.void %}
1839+
call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
1840+
{% elif method.lro %}
1841+
call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
1842+
operations_pb2.Operation(name='operations/spam')
1843+
)
1844+
{% elif method.server_streaming %}
1845+
call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True)
1846+
call.return_value.read = mock.AsyncMock(side_effect=[{{ method.output.ident }}()])
1847+
{% else %}
1848+
call.return_value = {{ '' }}
1849+
{%- if not method.server_streaming -%}
1850+
grpc_helpers_async.FakeUnaryUnaryCall
1851+
{%- else -%}
1852+
grpc_helpers_async.FakeStreamUnaryCall
1853+
{%- endif -%}({{ method.output.ident }}(
1854+
{% for field in method.output.fields.values() | rejectattr('message') %}{% if not field.oneof or field.proto3_optional %}
1855+
{{ field.name }}={{ field.mock_value }},
1856+
{% endif %}
1857+
{% endfor %}
1858+
))
1859+
{% endif %}{# method.void #}
1860+
await client.{{ method_name }}()
1861+
{% else %}{# if not is_async #}
1862+
call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string.
1863+
client.{{ method_name }}()
1864+
{% endif %}{# is_async #}
1865+
call.assert_called()
1866+
_, args, _ = call.mock_calls[0]
1867+
{% with method_settings = api.all_method_settings.get(method.meta.address.proto) %}
1868+
{% if method_settings is not none %}
1869+
{% for auto_populated_field in method_settings.auto_populated_fields %}
1870+
# Ensure that the uuid4 field is set according to AIP 4235
1871+
assert re.match(r"{{ uuid4_re }}", args[0].{{ auto_populated_field }})
1872+
# clear UUID field so that the check below succeeds
1873+
args[0].{{ auto_populated_field }} = None
1874+
{% endfor %}{# for auto_populated_field in method_settings.auto_populated_fields #}
1875+
{% endif %}{# if method_settings is not none #}
1876+
{% endwith %}{# method_settings #}
1877+
assert args[0] == {{ method.input.ident }}()
1878+
{% endmacro %}

0 commit comments

Comments
 (0)