Python Api響應驗證封裝
阿新 • • 發佈:2020-12-27
基礎驗證基類
首先,我們建立一個繼承自ABC類的BaseValidator類。因此,我可以建立一個抽象方法。從此類繼承的所有類都必須實現驗證功能。
其中有三個魔法函式,__set__()函式在為物件賦值時,自動傳入並執行。
from abc import ABC, abstractmethod class BaseValidator(ABC): @abstractmethod def validate(self, value): pass def __init__(self): self.value = None def__get__(self, obj, objtype): return self.value def __set__(self,obj, value): self.validate(value) self.value = value
建立驗證類
然後建立了3個驗證示例類。String,Integer和OneOf類。
String類具有最小和最大長度。驗證器功能檢查新值是否在最小和最大長度之間。
Integer類具有一個最小引數。驗證功能檢查新值是否大於此最小引數。
OneOf類很特殊。它接收可能的(字串)值列表。驗證功能檢查新值是否為可能的值之一。
class OneOf(BaseValidator): def __init__(self, values=list()): self.values = values def validate(self, value): if not isinstance(value, str): raise TypeError(f'{value} should be of type str') if not(value in self.values): raise ValueError(f'{value} should be one of {self.values}') class String(BaseValidator): def __init__(self, min_len = 8, max_len=12): self.min_len = min_len self.max_len = max_len def validate(self, value): if not isinstance(value, str): raise TypeError(f'{value} should be of type str') if len(value) < self.min_len: raise ValueError(f'length of {value} should be at least {self.min_len}') if len(value) > self.max_len: raise ValueError(f'length of {value} should be not bigger than {self.max_len}') class Integer(BaseValidator): def __init__(self, minimum=21): self.minimum = minimum def validate(self, value): if not isinstance(value, int): raise TypeError(f'{value} should be of type int') if value < self.minimum: raise ValueError(f'{value} should be at least {self.minimum}')
構建unittest測試
這裡ReplyValidator和Reply寫死了,在實際工作中,可以將驗證類物件與資料一起傳入Reply,在ReplyValidator中迴圈例項化物件,並以列表返回,再迴圈賦值驗證。
import unittest class ReplyValidator(object): name = String() age = Integer() interest = OneOf(["testing", "programming", "agile"]) class Reply(): def __init__(self, data): self.validator = ReplyValidator() self.validator.name = data["name"] self.validator.age = data["age"] self.validator.interest = data["interest"] class BaiduTest(unittest.TestCase): def setUp(self): pass def test_baidu(self): reply_data = dict(name="test", street="testing street", age=34, interest="testing") reply = Reply(reply_data) def tearDown(self): pass if __name__ == "__main__": unittest.main()