]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Closing AsyncClient in all tests (#871) (#1219)
authorcdeler <serj.krotov@gmail.com>
Mon, 31 Aug 2020 15:02:28 +0000 (18:02 +0300)
committerGitHub <noreply@github.com>
Mon, 31 Aug 2020 15:02:28 +0000 (18:02 +0300)
All over the AsyncClient invocation is made using context manager or with try-finally block

tests/client/test_auth.py
tests/test_asgi.py
tests/test_multipart.py

index ae35e2cd35d983fc82231898943470bbc2111881..2162e122490d8bcf1b3413f8017131728f53d997 100644 (file)
@@ -5,12 +5,11 @@ import typing
 import httpcore
 import pytest
 
+import httpx
 from httpx import (
     URL,
-    AsyncClient,
     Auth,
     BasicAuth,
-    Client,
     DigestAuth,
     ProtocolError,
     Request,
@@ -189,8 +188,8 @@ async def test_basic_auth() -> None:
     url = "https://example.org/"
     auth = ("tomchristie", "password123")
 
-    client = AsyncClient(transport=AsyncMockTransport())
-    response = await client.get(url, auth=auth)
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        response = await client.get(url, auth=auth)
 
     assert response.status_code == 200
     assert response.json() == {"auth": "Basic dG9tY2hyaXN0aWU6cGFzc3dvcmQxMjM="}
@@ -200,8 +199,8 @@ async def test_basic_auth() -> None:
 async def test_basic_auth_in_url() -> None:
     url = "https://tomchristie:password123@example.org/"
 
-    client = AsyncClient(transport=AsyncMockTransport())
-    response = await client.get(url)
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        response = await client.get(url)
 
     assert response.status_code == 200
     assert response.json() == {"auth": "Basic dG9tY2hyaXN0aWU6cGFzc3dvcmQxMjM="}
@@ -212,8 +211,8 @@ async def test_basic_auth_on_session() -> None:
     url = "https://example.org/"
     auth = ("tomchristie", "password123")
 
-    client = AsyncClient(transport=AsyncMockTransport(), auth=auth)
-    response = await client.get(url)
+    async with httpx.AsyncClient(transport=AsyncMockTransport(), auth=auth) as client:
+        response = await client.get(url)
 
     assert response.status_code == 200
     assert response.json() == {"auth": "Basic dG9tY2hyaXN0aWU6cGFzc3dvcmQxMjM="}
@@ -227,8 +226,8 @@ async def test_custom_auth() -> None:
         request.headers["Authorization"] = "Token 123"
         return request
 
-    client = AsyncClient(transport=AsyncMockTransport())
-    response = await client.get(url, auth=auth)
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        response = await client.get(url, auth=auth)
 
     assert response.status_code == 200
     assert response.json() == {"auth": "Token 123"}
@@ -239,8 +238,8 @@ async def test_netrc_auth() -> None:
     os.environ["NETRC"] = str(FIXTURES_DIR / ".netrc")
     url = "http://netrcexample.org"
 
-    client = AsyncClient(transport=AsyncMockTransport())
-    response = await client.get(url)
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        response = await client.get(url)
 
     assert response.status_code == 200
     assert response.json() == {
@@ -253,8 +252,8 @@ async def test_auth_header_has_priority_over_netrc() -> None:
     os.environ["NETRC"] = str(FIXTURES_DIR / ".netrc")
     url = "http://netrcexample.org"
 
-    client = AsyncClient(transport=AsyncMockTransport())
-    response = await client.get(url, headers={"Authorization": "Override"})
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        response = await client.get(url, headers={"Authorization": "Override"})
 
     assert response.status_code == 200
     assert response.json() == {"auth": "Override"}
@@ -265,14 +264,18 @@ async def test_trust_env_auth() -> None:
     os.environ["NETRC"] = str(FIXTURES_DIR / ".netrc")
     url = "http://netrcexample.org"
 
-    client = AsyncClient(transport=AsyncMockTransport(), trust_env=False)
-    response = await client.get(url)
+    async with httpx.AsyncClient(
+        transport=AsyncMockTransport(), trust_env=False
+    ) as client:
+        response = await client.get(url)
 
     assert response.status_code == 200
     assert response.json() == {"auth": None}
 
-    client = AsyncClient(transport=AsyncMockTransport(), trust_env=True)
-    response = await client.get(url)
+    async with httpx.AsyncClient(
+        transport=AsyncMockTransport(), trust_env=True
+    ) as client:
+        response = await client.get(url)
 
     assert response.status_code == 200
     assert response.json() == {
@@ -285,8 +288,8 @@ async def test_auth_disable_per_request() -> None:
     url = "https://example.org/"
     auth = ("tomchristie", "password123")
 
-    client = AsyncClient(transport=AsyncMockTransport(), auth=auth)
-    response = await client.get(url, auth=None)
+    async with httpx.AsyncClient(transport=AsyncMockTransport(), auth=auth) as client:
+        response = await client.get(url, auth=None)
 
     assert response.status_code == 200
     assert response.json() == {"auth": None}
@@ -304,41 +307,40 @@ async def test_auth_hidden_header() -> None:
     url = "https://example.org/"
     auth = ("example-username", "example-password")
 
-    client = AsyncClient(transport=AsyncMockTransport())
-    response = await client.get(url, auth=auth)
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        response = await client.get(url, auth=auth)
 
     assert "'authorization': '[secure]'" in str(response.request.headers)
 
 
 @pytest.mark.asyncio
 async def test_auth_property() -> None:
-    client = AsyncClient(transport=AsyncMockTransport())
-    assert client.auth is None
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        assert client.auth is None
 
-    client.auth = ("tomchristie", "password123")  # type: ignore
-    assert isinstance(client.auth, BasicAuth)
+        client.auth = ("tomchristie", "password123")  # type: ignore
+        assert isinstance(client.auth, BasicAuth)
 
-    url = "https://example.org/"
-    response = await client.get(url)
-    assert response.status_code == 200
-    assert response.json() == {"auth": "Basic dG9tY2hyaXN0aWU6cGFzc3dvcmQxMjM="}
+        url = "https://example.org/"
+        response = await client.get(url)
+        assert response.status_code == 200
+        assert response.json() == {"auth": "Basic dG9tY2hyaXN0aWU6cGFzc3dvcmQxMjM="}
 
 
 @pytest.mark.asyncio
 async def test_auth_invalid_type() -> None:
     with pytest.raises(TypeError):
-        client = AsyncClient(
+        client = httpx.AsyncClient(
             transport=AsyncMockTransport(),
             auth="not a tuple, not a callable",  # type: ignore
         )
 
-    client = AsyncClient(transport=AsyncMockTransport())
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        with pytest.raises(TypeError):
+            await client.get(auth="not a tuple, not a callable")  # type: ignore
 
-    with pytest.raises(TypeError):
-        await client.get(auth="not a tuple, not a callable")  # type: ignore
-
-    with pytest.raises(TypeError):
-        client.auth = "not a tuple, not a callable"  # type: ignore
+        with pytest.raises(TypeError):
+            client.auth = "not a tuple, not a callable"  # type: ignore
 
 
 @pytest.mark.asyncio
@@ -346,8 +348,8 @@ async def test_digest_auth_returns_no_auth_if_no_digest_header_in_response() ->
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
 
-    client = AsyncClient(transport=AsyncMockTransport())
-    response = await client.get(url, auth=auth)
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        response = await client.get(url, auth=auth)
 
     assert response.status_code == 200
     assert response.json() == {"auth": None}
@@ -360,10 +362,10 @@ async def test_digest_auth_200_response_including_digest_auth_header() -> None:
     auth = DigestAuth(username="tomchristie", password="password123")
     auth_header = b'Digest realm="realm@host.com",qop="auth",nonce="abc",opaque="xyz"'
 
-    client = AsyncClient(
+    async with httpx.AsyncClient(
         transport=AsyncMockTransport(auth_header=auth_header, status_code=200)
-    )
-    response = await client.get(url, auth=auth)
+    ) as client:
+        response = await client.get(url, auth=auth)
 
     assert response.status_code == 200
     assert response.json() == {"auth": None}
@@ -375,8 +377,10 @@ async def test_digest_auth_401_response_without_digest_auth_header() -> None:
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
 
-    client = AsyncClient(transport=AsyncMockTransport(auth_header=b"", status_code=401))
-    response = await client.get(url, auth=auth)
+    async with httpx.AsyncClient(
+        transport=AsyncMockTransport(auth_header=b"", status_code=401)
+    ) as client:
+        response = await client.get(url, auth=auth)
 
     assert response.status_code == 401
     assert response.json() == {"auth": None}
@@ -403,8 +407,10 @@ async def test_digest_auth(
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
 
-    client = AsyncClient(transport=MockDigestAuthTransport(algorithm=algorithm))
-    response = await client.get(url, auth=auth)
+    async with httpx.AsyncClient(
+        transport=MockDigestAuthTransport(algorithm=algorithm)
+    ) as client:
+        response = await client.get(url, auth=auth)
 
     assert response.status_code == 200
     assert len(response.history) == 1
@@ -433,8 +439,8 @@ async def test_digest_auth_no_specified_qop() -> None:
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
 
-    client = AsyncClient(transport=MockDigestAuthTransport(qop=""))
-    response = await client.get(url, auth=auth)
+    async with httpx.AsyncClient(transport=MockDigestAuthTransport(qop="")) as client:
+        response = await client.get(url, auth=auth)
 
     assert response.status_code == 200
     assert len(response.history) == 1
@@ -464,8 +470,8 @@ async def test_digest_auth_qop_including_spaces_and_auth_returns_auth(qop: str)
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
 
-    client = AsyncClient(transport=MockDigestAuthTransport(qop=qop))
-    response = await client.get(url, auth=auth)
+    async with httpx.AsyncClient(transport=MockDigestAuthTransport(qop=qop)) as client:
+        response = await client.get(url, auth=auth)
 
     assert response.status_code == 200
     assert len(response.history) == 1
@@ -475,20 +481,24 @@ async def test_digest_auth_qop_including_spaces_and_auth_returns_auth(qop: str)
 async def test_digest_auth_qop_auth_int_not_implemented() -> None:
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
-    client = AsyncClient(transport=MockDigestAuthTransport(qop="auth-int"))
 
-    with pytest.raises(NotImplementedError):
-        await client.get(url, auth=auth)
+    async with httpx.AsyncClient(
+        transport=MockDigestAuthTransport(qop="auth-int")
+    ) as client:
+        with pytest.raises(NotImplementedError):
+            await client.get(url, auth=auth)
 
 
 @pytest.mark.asyncio
 async def test_digest_auth_qop_must_be_auth_or_auth_int() -> None:
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
-    client = AsyncClient(transport=MockDigestAuthTransport(qop="not-auth"))
 
-    with pytest.raises(ProtocolError):
-        await client.get(url, auth=auth)
+    async with httpx.AsyncClient(
+        transport=MockDigestAuthTransport(qop="not-auth")
+    ) as client:
+        with pytest.raises(ProtocolError):
+            await client.get(url, auth=auth)
 
 
 @pytest.mark.asyncio
@@ -496,10 +506,10 @@ async def test_digest_auth_incorrect_credentials() -> None:
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
 
-    client = AsyncClient(
+    async with httpx.AsyncClient(
         transport=MockDigestAuthTransport(send_response_after_attempt=2)
-    )
-    response = await client.get(url, auth=auth)
+    ) as client:
+        response = await client.get(url, auth=auth)
 
     assert response.status_code == 401
     assert len(response.history) == 1
@@ -521,12 +531,11 @@ async def test_async_digest_auth_raises_protocol_error_on_malformed_header(
 ) -> None:
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
-    client = AsyncClient(
+    async with httpx.AsyncClient(
         transport=AsyncMockTransport(auth_header=auth_header, status_code=401)
-    )
-
-    with pytest.raises(ProtocolError):
-        await client.get(url, auth=auth)
+    ) as client:
+        with pytest.raises(ProtocolError):
+            await client.get(url, auth=auth)
 
 
 @pytest.mark.parametrize(
@@ -544,12 +553,12 @@ def test_sync_digest_auth_raises_protocol_error_on_malformed_header(
 ) -> None:
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
-    client = Client(
-        transport=SyncMockTransport(auth_header=auth_header, status_code=401)
-    )
 
-    with pytest.raises(ProtocolError):
-        client.get(url, auth=auth)
+    with httpx.Client(
+        transport=SyncMockTransport(auth_header=auth_header, status_code=401)
+    ) as client:
+        with pytest.raises(ProtocolError):
+            client.get(url, auth=auth)
 
 
 @pytest.mark.asyncio
@@ -560,9 +569,12 @@ async def test_async_auth_history() -> None:
     """
     url = "https://example.org/"
     auth = RepeatAuth(repeat=2)
-    client = AsyncClient(transport=AsyncMockTransport(auth_header=b"abc"))
 
-    response = await client.get(url, auth=auth)
+    async with httpx.AsyncClient(
+        transport=AsyncMockTransport(auth_header=b"abc")
+    ) as client:
+        response = await client.get(url, auth=auth)
+
     assert response.status_code == 200
     assert response.json() == {"auth": "Repeat abc.abc"}
 
@@ -584,9 +596,10 @@ def test_sync_auth_history() -> None:
     """
     url = "https://example.org/"
     auth = RepeatAuth(repeat=2)
-    client = Client(transport=SyncMockTransport(auth_header=b"abc"))
 
-    response = client.get(url, auth=auth)
+    with httpx.Client(transport=SyncMockTransport(auth_header=b"abc")) as client:
+        response = client.get(url, auth=auth)
+
     assert response.status_code == 200
     assert response.json() == {"auth": "Repeat abc.abc"}
 
@@ -605,13 +618,13 @@ def test_sync_auth_history() -> None:
 async def test_digest_auth_unavailable_streaming_body():
     url = "https://example.org/"
     auth = DigestAuth(username="tomchristie", password="password123")
-    client = AsyncClient(transport=AsyncMockTransport())
 
     async def streaming_body():
         yield b"Example request body"  # pragma: nocover
 
-    with pytest.raises(RequestBodyUnavailable):
-        await client.post(url, data=streaming_body(), auth=auth)
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        with pytest.raises(RequestBodyUnavailable):
+            await client.post(url, data=streaming_body(), auth=auth)
 
 
 @pytest.mark.asyncio
@@ -622,9 +635,9 @@ async def test_async_auth_reads_response_body() -> None:
     """
     url = "https://example.org/"
     auth = ResponseBodyAuth("xyz")
-    client = AsyncClient(transport=AsyncMockTransport())
+    async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+        response = await client.get(url, auth=auth)
 
-    response = await client.get(url, auth=auth)
     assert response.status_code == 200
     assert response.json() == {"auth": '{"auth": "xyz"}'}
 
@@ -636,8 +649,9 @@ def test_sync_auth_reads_response_body() -> None:
     """
     url = "https://example.org/"
     auth = ResponseBodyAuth("xyz")
-    client = Client(transport=SyncMockTransport())
 
-    response = client.get(url, auth=auth)
+    with httpx.Client(transport=SyncMockTransport()) as client:
+        response = client.get(url, auth=auth)
+
     assert response.status_code == 200
     assert response.json() == {"auth": '{"auth": "xyz"}'}
index c59ef7c30e963941768855ad989ae63435569bc7..00e169af37a8f921367d8231fb72f29689ff3fda 100644 (file)
@@ -43,39 +43,41 @@ async def raise_exc_after_response(scope, receive, send):
 
 @pytest.mark.usefixtures("async_environment")
 async def test_asgi():
-    client = httpx.AsyncClient(app=hello_world)
-    response = await client.get("http://www.example.org/")
+    async with httpx.AsyncClient(app=hello_world) as client:
+        response = await client.get("http://www.example.org/")
+
     assert response.status_code == 200
     assert response.text == "Hello, World!"
 
 
 @pytest.mark.usefixtures("async_environment")
 async def test_asgi_upload():
-    client = httpx.AsyncClient(app=echo_body)
-    response = await client.post("http://www.example.org/", data=b"example")
+    async with httpx.AsyncClient(app=echo_body) as client:
+        response = await client.post("http://www.example.org/", data=b"example")
+
     assert response.status_code == 200
     assert response.text == "example"
 
 
 @pytest.mark.usefixtures("async_environment")
 async def test_asgi_exc():
-    client = httpx.AsyncClient(app=raise_exc)
-    with pytest.raises(ValueError):
-        await client.get("http://www.example.org/")
+    async with httpx.AsyncClient(app=raise_exc) as client:
+        with pytest.raises(ValueError):
+            await client.get("http://www.example.org/")
 
 
 @pytest.mark.usefixtures("async_environment")
 async def test_asgi_http_error():
-    client = httpx.AsyncClient(app=partial(raise_exc, exc=RuntimeError))
-    with pytest.raises(RuntimeError):
-        await client.get("http://www.example.org/")
+    async with httpx.AsyncClient(app=partial(raise_exc, exc=RuntimeError)) as client:
+        with pytest.raises(RuntimeError):
+            await client.get("http://www.example.org/")
 
 
 @pytest.mark.usefixtures("async_environment")
 async def test_asgi_exc_after_response():
-    client = httpx.AsyncClient(app=raise_exc_after_response)
-    with pytest.raises(ValueError):
-        await client.get("http://www.example.org/")
+    async with httpx.AsyncClient(app=raise_exc_after_response) as client:
+        with pytest.raises(ValueError):
+            await client.get("http://www.example.org/")
 
 
 @pytest.mark.usefixtures("async_environment")
@@ -105,7 +107,8 @@ async def test_asgi_disconnect_after_response_complete():
         message = await receive()
         disconnect = message.get("type") == "http.disconnect"
 
-    client = httpx.AsyncClient(app=read_body)
-    response = await client.post("http://www.example.org/", data=b"example")
+    async with httpx.AsyncClient(app=read_body) as client:
+        response = await client.post("http://www.example.org/", data=b"example")
+
     assert response.status_code == 200
     assert disconnect
index 3230f927eb14ce2c0dbe964e4682342fa295c641..fccfdcd21e24b2a323568f6117b44e5db090954e 100644 (file)
@@ -35,76 +35,79 @@ class MockTransport(httpcore.AsyncHTTPTransport):
 @pytest.mark.parametrize(("value,output"), (("abc", b"abc"), (b"abc", b"abc")))
 @pytest.mark.asyncio
 async def test_multipart(value, output):
-    client = httpx.AsyncClient(transport=MockTransport())
-
-    # Test with a single-value 'data' argument, and a plain file 'files' argument.
-    data = {"text": value}
-    files = {"file": io.BytesIO(b"<file content>")}
-    response = await client.post("http://127.0.0.1:8000/", data=data, files=files)
-    assert response.status_code == 200
-
-    # We're using the cgi module to verify the behavior here, which is a
-    # bit grungy, but sufficient just for our testing purposes.
-    boundary = response.request.headers["Content-Type"].split("boundary=")[-1]
-    content_length = response.request.headers["Content-Length"]
-    pdict: dict = {
-        "boundary": boundary.encode("ascii"),
-        "CONTENT-LENGTH": content_length,
-    }
-    multipart = cgi.parse_multipart(io.BytesIO(response.content), pdict)
-
-    # Note that the expected return type for text fields
-    # appears to differs from 3.6 to 3.7+
-    assert multipart["text"] == [output.decode()] or multipart["text"] == [output]
-    assert multipart["file"] == [b"<file content>"]
+    async with httpx.AsyncClient(transport=MockTransport()) as client:
+        # Test with a single-value 'data' argument, and a plain file 'files' argument.
+        data = {"text": value}
+        files = {"file": io.BytesIO(b"<file content>")}
+        response = await client.post("http://127.0.0.1:8000/", data=data, files=files)
+        assert response.status_code == 200
+
+        # We're using the cgi module to verify the behavior here, which is a
+        # bit grungy, but sufficient just for our testing purposes.
+        boundary = response.request.headers["Content-Type"].split("boundary=")[-1]
+        content_length = response.request.headers["Content-Length"]
+        pdict: dict = {
+            "boundary": boundary.encode("ascii"),
+            "CONTENT-LENGTH": content_length,
+        }
+        multipart = cgi.parse_multipart(io.BytesIO(response.content), pdict)
+
+        # Note that the expected return type for text fields
+        # appears to differs from 3.6 to 3.7+
+        assert multipart["text"] == [output.decode()] or multipart["text"] == [output]
+        assert multipart["file"] == [b"<file content>"]
 
 
 @pytest.mark.parametrize(("key"), (b"abc", 1, 2.3, None))
 @pytest.mark.asyncio
 async def test_multipart_invalid_key(key):
-    client = httpx.AsyncClient(transport=MockTransport())
-    data = {key: "abc"}
-    files = {"file": io.BytesIO(b"<file content>")}
-    with pytest.raises(TypeError) as e:
-        await client.post("http://127.0.0.1:8000/", data=data, files=files)
-    assert "Invalid type for name" in str(e.value)
+    async with httpx.AsyncClient(transport=MockTransport()) as client:
+        data = {key: "abc"}
+        files = {"file": io.BytesIO(b"<file content>")}
+        with pytest.raises(TypeError) as e:
+            await client.post(
+                "http://127.0.0.1:8000/",
+                data=data,
+                files=files,
+            )
+        assert "Invalid type for name" in str(e.value)
 
 
 @pytest.mark.parametrize(("value"), (1, 2.3, None, [None, "abc"], {None: "abc"}))
 @pytest.mark.asyncio
 async def test_multipart_invalid_value(value):
-    client = httpx.AsyncClient(transport=MockTransport())
-    data = {"text": value}
-    files = {"file": io.BytesIO(b"<file content>")}
-    with pytest.raises(TypeError) as e:
-        await client.post("http://127.0.0.1:8000/", data=data, files=files)
-    assert "Invalid type for value" in str(e.value)
+    async with httpx.AsyncClient(transport=MockTransport()) as client:
+        data = {"text": value}
+        files = {"file": io.BytesIO(b"<file content>")}
+        with pytest.raises(TypeError) as e:
+            await client.post("http://127.0.0.1:8000/", data=data, files=files)
+        assert "Invalid type for value" in str(e.value)
 
 
 @pytest.mark.asyncio
 async def test_multipart_file_tuple():
-    client = httpx.AsyncClient(transport=MockTransport())
-
-    # Test with a list of values 'data' argument, and a tuple style 'files' argument.
-    data = {"text": ["abc"]}
-    files = {"file": ("name.txt", io.BytesIO(b"<file content>"))}
-    response = await client.post("http://127.0.0.1:8000/", data=data, files=files)
-    assert response.status_code == 200
-
-    # We're using the cgi module to verify the behavior here, which is a
-    # bit grungy, but sufficient just for our testing purposes.
-    boundary = response.request.headers["Content-Type"].split("boundary=")[-1]
-    content_length = response.request.headers["Content-Length"]
-    pdict: dict = {
-        "boundary": boundary.encode("ascii"),
-        "CONTENT-LENGTH": content_length,
-    }
-    multipart = cgi.parse_multipart(io.BytesIO(response.content), pdict)
-
-    # Note that the expected return type for text fields
-    # appears to differs from 3.6 to 3.7+
-    assert multipart["text"] == ["abc"] or multipart["text"] == [b"abc"]
-    assert multipart["file"] == [b"<file content>"]
+    async with httpx.AsyncClient(transport=MockTransport()) as client:
+        # Test with a list of values 'data' argument,
+        #     and a tuple style 'files' argument.
+        data = {"text": ["abc"]}
+        files = {"file": ("name.txt", io.BytesIO(b"<file content>"))}
+        response = await client.post("http://127.0.0.1:8000/", data=data, files=files)
+        assert response.status_code == 200
+
+        # We're using the cgi module to verify the behavior here, which is a
+        # bit grungy, but sufficient just for our testing purposes.
+        boundary = response.request.headers["Content-Type"].split("boundary=")[-1]
+        content_length = response.request.headers["Content-Length"]
+        pdict: dict = {
+            "boundary": boundary.encode("ascii"),
+            "CONTENT-LENGTH": content_length,
+        }
+        multipart = cgi.parse_multipart(io.BytesIO(response.content), pdict)
+
+        # Note that the expected return type for text fields
+        # appears to differs from 3.6 to 3.7+
+        assert multipart["text"] == ["abc"] or multipart["text"] == [b"abc"]
+        assert multipart["file"] == [b"<file content>"]
 
 
 def test_multipart_encode(tmp_path: typing.Any) -> None: