Coverage for tests / test_validate_response.py: 100%

51 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-12 18:15 +0000

1from typing import Optional, Union 1abcd

2 

3import pytest 1abcd

4from fastapi import FastAPI 1abcd

5from fastapi.exceptions import ResponseValidationError 1abcd

6from fastapi.testclient import TestClient 1abcd

7from pydantic import BaseModel 1abcd

8 

9app = FastAPI() 1abcd

10 

11 

12class Item(BaseModel): 1abcd

13 name: str 1abcd

14 price: Optional[float] = None 1abcd

15 owner_ids: Optional[list[int]] = None 1abcd

16 

17 

18@app.get("/items/invalid", response_model=Item) 1abcd

19def get_invalid(): 1abcd

20 return {"name": "invalid", "price": "foo"} 1klm

21 

22 

23@app.get("/items/invalidnone", response_model=Item) 1abcd

24def get_invalid_none(): 1abcd

25 return None 1nop

26 

27 

28@app.get("/items/validnone", response_model=Union[Item, None]) 1abcd

29def get_valid_none(send_none: bool = False): 1abcd

30 if send_none: 1efghij

31 return None 1fhj

32 else: 

33 return {"name": "invalid", "price": 3.2} 1egi

34 

35 

36@app.get("/items/innerinvalid", response_model=Item) 1abcd

37def get_innerinvalid(): 1abcd

38 return {"name": "double invalid", "price": "foo", "owner_ids": ["foo", "bar"]} 1qrs

39 

40 

41@app.get("/items/invalidlist", response_model=list[Item]) 1abcd

42def get_invalidlist(): 1abcd

43 return [ 1tuv

44 {"name": "foo"}, 

45 {"name": "bar", "price": "bar"}, 

46 {"name": "baz", "price": "baz"}, 

47 ] 

48 

49 

50client = TestClient(app) 1abcd

51 

52 

53def test_invalid(): 1abcd

54 with pytest.raises(ResponseValidationError): 1klm

55 client.get("/items/invalid") 1klm

56 

57 

58def test_invalid_none(): 1abcd

59 with pytest.raises(ResponseValidationError): 1nop

60 client.get("/items/invalidnone") 1nop

61 

62 

63def test_valid_none_data(): 1abcd

64 response = client.get("/items/validnone") 1egi

65 data = response.json() 1egi

66 assert response.status_code == 200 1egi

67 assert data == {"name": "invalid", "price": 3.2, "owner_ids": None} 1egi

68 

69 

70def test_valid_none_none(): 1abcd

71 response = client.get("/items/validnone", params={"send_none": "true"}) 1fhj

72 data = response.json() 1fhj

73 assert response.status_code == 200 1fhj

74 assert data is None 1fhj

75 

76 

77def test_double_invalid(): 1abcd

78 with pytest.raises(ResponseValidationError): 1qrs

79 client.get("/items/innerinvalid") 1qrs

80 

81 

82def test_invalid_list(): 1abcd

83 with pytest.raises(ResponseValidationError): 1tuv

84 client.get("/items/invalidlist") 1tuv