【问题标题】:Unit Testing a method that creates a table with indexes单元测试一种创建带有索引的表的方法
【发布时间】:2019-11-07 06:33:58
【问题描述】:

我为测试创建了这个假数据库,但我不知道如何从这里继续。我知道我需要创建具有收益率回报的预期场景并将结果与​​预期结果进行比较等等,但我不知道如何开始,我只需要一个起点。这对我来说是全新的,所以如果这是一个愚蠢的问题,请向大家道歉。

public class IndexTests : DataAccessFixture
{
    [Test]
    public void CreateTableWithIndex()
    {
        var db = this.database.Create();
        var table = db.DefineTable("IndexedTable");

        table.Columns.Add("Id", FieldType.Guid, false, true);
        table.Columns.Add("CustomerNumber", FieldType.VarChar, 50);
        table.Columns.Add("Name", FieldType.VarChar, 50);

        table.Indices.Add("IX_Name", false, "Name");
        table.Indices.Add("IX_CustomerNumber", true, "CustomerNumber");

        db.Execute();

        this.database.DropTable(table.Name);
    }
}

【问题讨论】:

  • 那么下一步是检查表是否实际创建了?登录数据库并检查
  • 我认为对这段代码进行单元测试没有多大意义。你到底希望你的测试能达到什么目的?您要测试的只是核心数据库类是否正常工作,这些已经进行了单元测试。 This is a fallacy of 100% coverage。如果您坚持对此进行单元测试,那么您需要概述您的测试究竟是什么,您的场景是什么以及有效和无效的测试是什么样的

标签: c# sql unit-testing nunit


【解决方案1】:

首先,您应该避免在测试类中使用database 字段。 这可能会干扰可能使用同一对象同时运行的其他测试,这可能会或可能不会混淆您的结果(但可能会)。

哪个是你的假数据库? 字段database 还是来自database.Create() 的结果? 如果是后者,那么您的测试实际上只是在测试您的假代码,而不是您的产品代码。

由于不清楚您使用的是 custom types 还是 bcl types,我将继续假设您正在测试您的自定义类型。 如果databasedbtable 实际上是bcl 类型,那么不要再阅读了。 测试这些类没有意义。 话虽如此,db.Execute() 到底是做什么的?

您目前正在同时测试多个事物,这应该避免。 从创建表的测试开始并检查它是否存在。 您还需要一个测试来确保没有抛出异常。

[Test]
public void DefineTableDoesNotThrow() {

    // arrange
    var database = // create your instance here
    var db = database.Create();
    var table = null;

    // act & assert
    Assert.DoesNotThrow(() => table = db.DefineTable("IndexedTable"));

    // clean up
    database.DropTable("IndexedTable");

}
[Test]
public void DefineTable() {

    // arrange
    var database = // create your instance here
    var db = database.Create();

    // act
    var table = db.DefineTable("IndexedTable");

    // assert
    // check if your table was created and exists.
    // do not care about the actual columns in here.

    // clean up
    database.DropTable("IndexedTable");

}

接下来,您要测试您的列是否按照您想要的方式创建。 这是另一个功能,所以它应该是另一个测试。 它的工作方式与DefineTable 类似,您首先要确保它不会引发异常,然后再担心它是否正常工作。

[Test]
public void ColumnAddDoesNotThrow() {

    // arrange
    var database = // create your instance here
    var db = database.Create();
    var table = db.DefineTable("IndexedTable");

    // act & assert
    Assert.DoesNotThrow(() => table.Columns.Add("Id", FieldType.Guid, false, true));

    // clean up
    database.DropTable("IndexedTable");

}
[Test]
public void ColumnAdd() {

    // arrange
    var database = // create your instance here
    var db = database.Create();
    var table = db.DefineTable("IndexedTable");

    // act
    table.Columns.Add("Id", FieldType.Guid, false, true);

    // assert
    // check if your table now has the correct column

    // cleanup
    database.DropTable("IndexedTable");

}

接下来要做的最好的事情是让最后一个测试使用多个输入。 这允许您通过添加另一行代码来使用相同的代码测试边缘情况。 用[TestCaseAttribute(...)] 装饰测试并将所需的参数添加到您的测试方法中。 对于table.Column.Add(...) 的每一个可能的过载,都必须这样做。 不用说,table.Indices.Add(...) 也一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 2010-12-16
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多