Skip to content

Commit b5ba1e1

Browse files
Add negative test cases for non-serializable types
This commit addresses the issue where test cases were pre-serializing values (datetime, UUID, bytes, etc.) to strings, rather than testing how stores handle these types. Changes: - Add test_put_nonserializable_types parametrized test to base.py that verifies stores reject non-JSON-serializable Python types (datetime, date, time, UUID, bytes, tuple, set, function, type) by raising SerializationError - Update comments in cases.py to clarify that datetime/UUID/bytes test cases are testing string handling, not object handling - Reference negative tests in base.py where actual objects are tested This fulfills the requirement from issue #96 to include negative test cases that assert certain types should fail. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: William Easton <[email protected]>
1 parent 0fdf0e0 commit b5ba1e1

File tree

2 files changed

+31
-6
lines changed
  • key-value
    • key-value-aio/tests/stores
    • key-value-shared-test/src/key_value/shared_test

2 files changed

+31
-6
lines changed

key-value/key-value-aio/tests/stores/base.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,30 @@ async def test_empty_ttl(self, store: BaseStore):
4646
assert ttl == (None, None)
4747

4848
async def test_put_serialization_errors(self, store: BaseStore):
49-
"""Tests that the put method does not raise an exception when called on a new store."""
49+
"""Tests that the put method raises SerializationError for non-JSON-serializable Pydantic types."""
5050
with pytest.raises(SerializationError):
5151
await store.put(collection="test", key="test", value={"test": AnyHttpUrl("https://test.com")})
5252

53+
@pytest.mark.parametrize(
54+
"name,value",
55+
[
56+
("datetime", __import__("datetime").datetime.now(__import__("datetime").timezone.utc)),
57+
("date", __import__("datetime").date(2025, 1, 1)),
58+
("time", __import__("datetime").time(12, 0, 0)),
59+
("uuid", __import__("uuid").UUID("12345678-1234-5678-1234-567812345678")),
60+
("bytes", b"hello world"),
61+
("tuple", (1, 2, 3)),
62+
("set", {1, 2, 3}),
63+
("function", lambda x: x),
64+
("type", type("TestClass", (), {})),
65+
],
66+
ids=["datetime", "date", "time", "uuid", "bytes", "tuple", "set", "function", "type"],
67+
)
68+
async def test_put_nonserializable_types(self, store: BaseStore, name: str, value: Any): # pyright: ignore[reportUnusedParameter] # noqa: ARG002
69+
"""Tests that non-JSON-serializable Python types raise SerializationError."""
70+
with pytest.raises(SerializationError):
71+
await store.put(collection="test", key="test", value={"test": value})
72+
5373
async def test_get_put_get(self, store: BaseStore):
5474
assert await store.get(collection="test", key="test") is None
5575
await store.put(collection="test", key="test", value={"test": "test"})

key-value/key-value-shared-test/src/key_value/shared_test/cases.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ class Case:
5151
name="list-three", data={"list_key_1": [1, True, 3.0, "string"]}, json='{"list_key_1": [1, true, 3.0, "string"]}'
5252
)
5353

54-
# Datetime cases (serialized as ISO format strings)
54+
# ISO format string cases (these test string handling, not datetime object handling)
55+
# Note: Actual datetime/date/time objects are tested in negative test cases (base.py)
5556
DATETIME_CASE: Case = Case(
5657
name="datetime",
5758
data={"datetime_key": FIXED_DATETIME.isoformat()},
@@ -68,29 +69,33 @@ class Case:
6869
json='{"time_key": "00:00:00"}',
6970
)
7071

71-
# UUID case (serialized as string)
72+
# UUID string case (tests string handling, not UUID object handling)
73+
# Note: Actual UUID objects are tested in negative test cases (base.py)
7274
UUID_CASE: Case = Case(
7375
name="uuid",
7476
data={"uuid_key": str(FIXED_UUID)},
7577
json='{"uuid_key": "12345678-1234-5678-1234-567812345678"}',
7678
)
7779

78-
# Bytes case (base64 encoded)
80+
# Base64-encoded string case (tests string handling, not bytes object handling)
81+
# Note: Actual bytes objects are tested in negative test cases (base.py)
7982
BYTES_VALUE = b"hello world"
8083
BYTES_CASE: Case = Case(
8184
name="bytes",
8285
data={"bytes_key": base64.b64encode(BYTES_VALUE).decode("ascii")},
8386
json=f'{{"bytes_key": "{base64.b64encode(BYTES_VALUE).decode("ascii")}"}}',
8487
)
8588

86-
# Tuple case (serializes as list in JSON)
89+
# List case (tests list handling, not tuple object handling)
90+
# Note: Actual tuple objects are tested in negative test cases (base.py)
8791
TUPLE_CASE: Case = Case(
8892
name="tuple",
8993
data={"tuple_key": [1, "two", 3.0]},
9094
json='{"tuple_key": [1, "two", 3.0]}',
9195
)
9296

93-
# Set case (serializes as sorted list in JSON)
97+
# List case (tests list handling, not set object handling)
98+
# Note: Actual set objects are tested in negative test cases (base.py)
9499
SET_CASE: Case = Case(
95100
name="set",
96101
data={"set_key": [1, 2, 3]},

0 commit comments

Comments
 (0)