Coverage for tests/test_validate_response.py: 100%

51 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-12-04 08:29 +0000

1from typing import List, Optional, Union 1abcdefg

2 

3import pytest 1abcdefg

4from fastapi import FastAPI 1abcdefg

5from fastapi.exceptions import ResponseValidationError 1abcdefg

6from fastapi.testclient import TestClient 1abcdefg

7from pydantic import BaseModel 1abcdefg

8 

9app = FastAPI() 1abcdefg

10 

11 

12class Item(BaseModel): 1abcdefg

13 name: str 1abcdefg

14 price: Optional[float] = None 1abcdefg

15 owner_ids: Optional[List[int]] = None 1abcdefg

16 

17 

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

19def get_invalid(): 1abcdefg

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

21 

22 

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

24def get_invalid_none(): 1abcdefg

25 return None 1CDEFGHI

26 

27 

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

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

30 if send_none: 1hijklmnopqrstu

31 return None 1ikmoqsu

32 else: 

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

34 

35 

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

37def get_innerinvalid(): 1abcdefg

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

39 

40 

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

42def get_invalidlist(): 1abcdefg

43 return [ 1QRSTUVW

44 {"name": "foo"}, 

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

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

47 ] 

48 

49 

50client = TestClient(app) 1abcdefg

51 

52 

53def test_invalid(): 1abcdefg

54 with pytest.raises(ResponseValidationError): 1vwxyzAB

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

56 

57 

58def test_invalid_none(): 1abcdefg

59 with pytest.raises(ResponseValidationError): 1CDEFGHI

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

61 

62 

63def test_valid_none_data(): 1abcdefg

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

65 data = response.json() 1hjlnprt

66 assert response.status_code == 200 1hjlnprt

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

68 

69 

70def test_valid_none_none(): 1abcdefg

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

72 data = response.json() 1ikmoqsu

73 assert response.status_code == 200 1ikmoqsu

74 assert data is None 1ikmoqsu

75 

76 

77def test_double_invalid(): 1abcdefg

78 with pytest.raises(ResponseValidationError): 1JKLMNOP

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

80 

81 

82def test_invalid_list(): 1abcdefg

83 with pytest.raises(ResponseValidationError): 1QRSTUVW

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