使用xUnit测试验证属性

目录

介绍

背景

使用代码

兴趣点


要测试REST API控制器的数据模型的验证,仅创建控制器类的实例并调用预期的方法是不可行的。它只是不测试验证,而只是跳过验证。我们需要一个真正的REST调用,但是我们需要从xUnit测试中获得它,而不是在手动启动应用程序时进行手动调用。两个软件包(RefitIntegrationFixture)可以为我们提供帮助,本文介绍了如何做。

介绍

使用xUnit,实际上很容易调用方法并验证响应。但是,方法调用并不总是反映实际情况。例如,在执行REST API调用以触发控制器方法时,可能首先要进行一些验证。该验证可能不是您的应用程序本身的一部分,而是由诸如[Required]验证属性设置的。本文介绍了如何轻松解决该问题。您不需要太多的样板代码,只需要正确的软件包和技巧即可。

背景

如果您对.NET CorexUnitREST API开发有一定的经验,它将帮助您理解此处给出的解释。

使用代码

这是我们要测试的方法。它根据名字和姓氏返回全名。中间名也可以包括在内,但是是可选的。

[HttpPost]
public ActionResult<string> Post([FromBody] Name value)
{
    return Ok($"{value.FirstName} {value.MiddleName} {value.LastName}");
}

从逻辑上讲,数据模型也需要实现。

public class Name
{
    [Required]
    public string FirstName { get; set; }

    public string MiddleName { get; set; }

    [Required]
    public string LastName { get; set; }
}

从上面显示的代码可以清楚地看出,名字和姓氏是必需的。中间名不是。

我们不能只从控制器实例中调用controller方法。这将跳过由验证属性触发的验证。但是,我们可以通过启动并执行REST调用来手动测试应用程序。从逻辑上讲,这很难用xUnit实现,也很难成为CI构建的一部分。解决方法如下:

首先,在使应用程序自托管成为测试的一部分时,我们需要一个Refit接口来进行一次调用。改装可作为NuGet包提供。接口如下所示:

public interface ILogicClient
{
    [Post("/api/logic")]
    Task<ApiResponse<string>> Post([Body] Name name);
}

现在,我们需要在测试中以编程方式创建一个实现和实例。为此,我们需要一个新的NuGet软件包,该软件包也支持自托管。该软件包(IntegrationFixture)也可以作为NuGet软件包使用

[Theory]
[InlineData("Boris","Alexander", "Johnson", 
             HttpStatusCode.OK, "Boris", "Alexander", "Johnson")]
[InlineData("Boris", "Alexander", null, HttpStatusCode.BadRequest)]
[InlineData(null, "Alexander", "Johnson", HttpStatusCode.BadRequest)]
[InlineData("Boris", "Alexander", "", HttpStatusCode.BadRequest)]
[InlineData("", "Alexander", "Johnson", HttpStatusCode.BadRequest)]
public async Task NamesTest(string firstName, string middleName, 
   string lastName, HttpStatusCode expectedStatusCode, params string[] responseContains)
{
    using (var fixture = 
           new RefitFixture<Startup, ILogicClient>(RestService.For<ILogicClient>))
    {
        var refitClient = fixture.GetRefitClient();
        var response = await refitClient.Post(new Name
        {
            FirstName = firstName,
            MiddleName = middleName,
            LastName = lastName,
        });

        var statusCode = response.StatusCode;

        Assert.Equal(expectedStatusCode, statusCode);
        var content = response.Content;

        foreach (var expectedResponse in responseContains)
        {
            Assert.Contains(expectedResponse, content);
        }
    }
}

从上面的代码可以清楚地看到,我们有几个测试用例。根据可用的名称,返回特定的状态码。这就是验证属性应该触发的内容,所以这就是我们要声明的内容。此外,当获得肯定结果时,我们还声明响应的内容。现在问题已解决。在这里RefitFixture至关重要。它知道用于启用应用程序自我托管的Startup类。此外,它也知道用于对自托管应用程序进行REST调用的改装接口ILogicClient。这就解决了我们的问题:我们可以使用xUnit测试验证属性,而无需启动应用程序。本文中的代码可在GitHub上获得

兴趣点

对我来说,提到的NuGet包中RefitFixture类确实很有帮助。当我刚开始开发.NET Core应用程序时,我手动执行了应用程序以测试验证。这不再需要。验证和其他类似中间件的事物可以使用xUnit进行测试,就像常规的单元测试一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值