我需要多个断言吗?Xunit测试



这是我第一次编写单元测试,我只有几个问题。我正在内存数据库测试我的服务,我想知道我是否正确地进行了。我的第一个问题是我需要在所有服务电话上进行多重断言吗?像我需要InsertProduct的断言吗?其次,我是否对此进行了测试,以便在每个服务调用上使用上下文的新实例?

[Fact]
public void ProductService_DeleteProduct_Test()
{
    // arrange
    var options = new DbContextOptionsBuilder<ApplicationDbContext>()
        .UseInMemoryDatabase(databaseName: "ProductService_DeleteProduct_Test")
        .Options;
    var product = new Product() { Id = Guid.NewGuid(), Name = "Product"};
    // act
    // insert
    using (var context = new ApplicationDbContext(options))
    {
        var service = new Service(context);
        service.ProductService.InsertProduct(product);
    }
    // delete
    using (var context = new ApplicationDbContext(options))
    {
        var service = new Service(context);
        service.ProductService.DeleteProducts(new List<Guid> { product.Id });
    }
    // assert
    using (var context = new ApplicationDbContext(options))
    {
        var service = new Service(context);
        Assert.Equal(0, service.ProductService.GetAllProducts().Count);
    }
}

我会反对测试的结构。也就是说,您正在使用服务(生产代码)来准备基础数据库。您还使用生产代码来做出断言。

如果生产代码的任何部分不正确,则该测试将失败。但是,该测试旨在断言删除功能做得正确。

因此,我将以以下方式重写整个测试:

[Fact]
public void ProductService_DeleteProduct_Test()
{
    // arrange
    var options = new DbContextOptionsBuilder<ApplicationDbContext>()
        .UseInMemoryDatabase(databaseName: "ProductService_DeleteProduct_Test")
        .Options;
    var product = new Product() { Id = Guid.NewGuid(), Name = "Product"};
    // Insert object using other means, i.e. direct INSERT statement
    // act
    using (var context = new ApplicationDbContext(options))
    {
        var service = new Service(context);
        service.ProductService.DeleteProducts(new List<Guid> { product.Id });
    }
    // assert
    // Execute SELECT COUNT(*) instruction to fetch previously existing row
    Assert.Equal(0, rowsCount);
}

这样,您只会在测试的代理部分触摸生产代码。这就是您使用服务对象从数据库中删除对象的部分。

随后的断言是针对标量值 count进行的,该标量值是直接在存储上执行的RAW SELECT语句的结果。

最重要的是,测试的各个部分都不取决于生产代码的正确性,除了DeleteProducts方法实际上是正在测试的方法。

,因此,您问题的答案是在此测试中只有一个断言。

回答您的第一个问题,我会说不。由于这是一个单元测试,并且您正在专门测试删除。我考虑设置的插入部分,因为您将系统进入要测试删除的状态。对于Zoran Horvat的观点,如果可以的话,通过服务本身以外的某些手段在数据库中放置一行。

要回答您的第二个问题,似乎没有必要使用三个块,您要在其中介绍三遍服务。我将插入,删除和断言使用,使用SUT的一个实例或服务。

但是,如果您有多个测试,这些测试都需要数据库中的一行,请考虑使用[设置]属性将每个测试都可以在手动之前调用的[设置]属性中移动到设置方法中。在这种情况下,您将使用上下文的多个实例。

相关内容

  • 没有找到相关文章

最新更新