Fluent Assertions 检查是不是所有端点都具有特定的 swagger 属性

Posted

技术标签:

【中文标题】Fluent Assertions 检查是不是所有端点都具有特定的 swagger 属性【英文标题】:Fluent Assertions check if all endpoints have a specific swagger attributeFluent Assertions 检查是否所有端点都具有特定的 swagger 属性 【发布时间】:2021-06-08 04:17:19 【问题描述】:

我想检查我的 ASP.NET Core API 控制器的所有端点是否具有如下所示的属性:

[SwaggerResponse(HttpStatusCode.OK,typeof(*different types*))]

我使用 xUnit 和 Fluent Assertions 来写这个:

[Fact]
public void EndpointsSwaggerAttribute()

      typeof(BaseController).Methods().Should().BeDecoratedWith<SwaggerResponseAttribute>(s =>(s.StatusCode == HttpStatusCode.OK.ToString()));

但它并不完全有效。它总是通过测试。 Base Controller是一个继承ControllerBase的helper类,所有的controller都继承Base Controller。

【问题讨论】:

你只检查 BaseController 而不是所有的控制器 inheriting from BaseController 【参考方案1】:

如果要检查 API 控制器的所有端点是否具有 SwaggerResponse 属性,则需要先获取 api 项目的程序集,然后获取项目中的所有方法:

public class UnitTest1

    [Fact]
    public void Test1()
    
        //if the unit test exsit in the api project...
        //Assembly asm = Assembly.GetExecutingAssembly();

        //if your unit test project seprate from the api project
        //you could get the api project assembly like below
        var asm = typeof(WeatherForecastController).Assembly;
        
        //get all the methods in project
        var methods = asm.GetTypes()
        .Where(type => typeof(ControllerBase).IsAssignableFrom(type)) 
        .SelectMany(type => type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)).ToList();
                    
        foreach (var method in methods)
                      
            //check if the method has SwaggerResponse attribute  
            var result = Attribute.IsDefined(method, typeof(SwaggerResponseAttribute));
            Assert.True(result, $"method.Name should be declared with SwaggerResponse Attribute");
        

    

【讨论】:

这正是我想要的,谢谢。是否可以使用此解决方案检查所有方法是否具有带有特定状态代码的 SwaggerResponseAttribute?【参考方案2】:

BaseController 有方法吗?如果没有,您需要首先列出具体类型并在其上使用Methods 扩展方法。

但是,我实际上会编写 HTTP API 测试(使用 ASP.NET Core HostBuilder)来验证 Swagger 端点的可观察输出是否正确。

【讨论】:

建议通过实际的 HTTP API 测试进行验证;) 我完全同意在自己的主机中运行 web api 进行测试以获得招摇,但你如何确保你没有错过任何注释? 您需要该注释才能让 Swagger 以某种方式返回某些内容,对吗?如果您知道这一点,我还希望有一个 HTTP 测试来验证这一点。 但是注释纯粹是为了记录目的。所以你可以有一个 HTTP 调用来检查你的端点是否返回了预期的类型,你也可以有一个 HTTP 调用来检查 Swagger 是否正确生成,但这并不意味着符号/返回类型文档已应用于端点和它出现在 Swagger 中。您可以解析 Swagger 并真正尝试每次调用以查看您得到的内容是否与 Swagger 声明的类型相对应,但如果检查注释就足够了,这似乎有点矫枉过正? 这是一个选择问题。我不想在测试中查看内部实现细节。【参考方案3】:

目前您只是直接在 BaseController 中查看方法,您必须获取所有子类:

        var baseControllerType = typeof(BaseController);
        var controllerTypes = baseControllerType.Assembly.GetTypes().Where(t => t.IsClass && t != type
                                                      && type.IsAssignableFrom(BaseController))

然后,您可以对每个控制器应用相同的逻辑。

【讨论】:

我不明白你为什么使用type。您的意思是使用 baseControllerType 吗? 是的对不起,我在本地做了一个小样,忘记改名字了:s

以上是关于Fluent Assertions 检查是不是所有端点都具有特定的 swagger 属性的主要内容,如果未能解决你的问题,请参考以下文章

Fluent Assertions:大致比较一个类的属性

Fluent Assertions BeEquivalentTo 用于在匹配字符串中具有大小写差异的混合对象

Fluent-ASsertions ShouldRaisePropertyChangeFor 不适用于异步任务?

如何使用 Fluent Assertions 引发异常?

使用 Fluent Assertions 库的多个断言

Fluent Assertions Should().BeEquivalentTo 只有私有字段