测试包装 api 路由的装饰器

Posted

技术标签:

【中文标题】测试包装 api 路由的装饰器【英文标题】:Testing a decorator that wraps api routes 【发布时间】:2019-07-09 00:27:42 【问题描述】:

我正在构建一个 rest api,我正在为 api 制作路线并偶然发现了一个问题。我正在使用flask restplus来构建api和marshmallow来验证客户端发送的json。

我的设计:我使用一个装饰器来包装每个 api 路由。此装饰器根据棉花糖模式验证客户端发送的 json,如果 json 验证,则装饰器让 api 路由运行。否则,如果在检查模式时 json 无效,它会在不运行路由的情况下将在使 json 无效时返回的错误返回给客户端。

我真的很喜欢这种设计,因为它显着减少了代码重复,它可以自动验证和无效客户端发布的数据,而无需我在每个 api 路由中做几乎相同的事情——检查客户端发送的 json,然后运行路线。

我唯一的问题是我不知道如何单元测试这个。我已经为特定的棉花糖 json 模式编写了测试,以检查在将无效数据传递给它们时它们是否会引发正确的验证错误。但是,现在我需要测试 api 路由以检查它们是否返回模式引发的验证错误。这似乎是单元测试的大量重复,因为我在测试架构时检查相同的错误,并在测试 api 路由/装饰器时再次检查。

因此,你们对我应该如何进行单元测试有什么建议吗?我应该专门测试 api 路由、单独测试装饰器和单独​​测试模式吗?或者我应该只测试 api 路由以检查它们是否返回了架构引发的正确错误?

提前致谢。

【问题讨论】:

【参考方案1】:

这可能是一个见仁见智的问题。

我不认为测试所有模式都有用,除非它们包含一些自定义代码,如自定义字段、验证器等。没有必要测试 marshmallow 本身,因为它已经被自己的测试广泛覆盖。因此,测试棉花糖模式只能用于检查您输入的字段名称和验证器是否正确。恕我直言,这对于低福利来说是相当冗长的。

我会测试装饰器:创建一个虚拟测试路线,装饰它,检查返回的错误是否正确。

决定是否值得为所有类型的错误测试所有路由取决于您。只要您的装饰器经过测试,测试路由只会检查装饰器是否应用于具有正确架构的路由。

有些人会争辩说,相反,他们只关心 API 本身,他们只需要测试路由。但这意味着要在所有路线上测试所有案例,所以这是很多重复。而且我不认为这符合单元测试,而是集成测试

请注意,您可以尝试使用 webargs(由 marshmallow 团队维护)来替换您的装饰器,但我不知道集成到 flask-restplus 中是否容易。

【讨论】:

如果你有棉花糖模式的自定义验证器怎么办。是否仍然不值得对每个模式或至少每个验证器进行单元测试? 是的,当然。测试你的代码并假设库被它自己的测试所覆盖。 (Marshmallow 进行了广泛的测试。) 如何确保我为棉花糖模式创建的自定义验证器在不为它们创建单元测试的情况下实际工作? 那么你的意思是我应该测试我为棉花糖创建的自定义验证器,因为它是我的代码,而不是担心测试内置验证器?此外,我应该测试装饰器以确保它正常工作以及我测试每个 api 路由是否纯粹基于意见?你说的对吗? @Jérôme 是的。确切地。我编辑了我的答案,希望能澄清这一点。

以上是关于测试包装 api 路由的装饰器的主要内容,如果未能解决你的问题,请参考以下文章

(Python) 将 Playwright Page 对象传递给包装函数的函数装饰器

[设计模式C++go]结构型模式:装饰器模式

[设计模式C++go]结构型模式:装饰器模式

[设计模式C++go]结构型模式:装饰器模式

如何在 python 中用我自己的包装第三方装饰器

Python装饰器