使用XUnit,ADO.NET,SQL Server进行单元测试

时间:2016-01-20 00:40:58

标签: c# sql-server ado.net xunit

这个问题是关于将XUnit与ADO.NET一起用于使用Nancy的待办事项列表应用程序。我希望对Assert.Equal测试失败的原因有所了解,即使输出看起来相同。

我有一个包含两个属性的Task类:iddescription

此应用的数据库具有相应的tasks表。用户输入用于描述,id是自动递增标识列。

Task类具有静态List属性All()。每项任务都会添加到All(),您可以通过调用Task.All()来检索所有任务的列表。

这是Task类:

namespace ToDoList
{
  public class Task
  {
    private int id;
    private string description;

    public Task(string Description, int Id = 0)
    {
      id = Id;
      description = Description;
    }

    public int GetId()
    {
      return id;
    }


    public string GetDescription()
    {
      return description;
    }

    public void SetDescription(string newDescription)
    {
      description = newDescription;
    }

    public static List<Task> All()
    {
      List<Task> AllTasks = new List<Task>{};

      SqlConnection conn = DB.Connection();
      SqlDataReader rdr = null;
      conn.Open();

      SqlCommand cmd = new SqlCommand("SELECT * FROM tasks", conn);
      rdr = cmd.ExecuteReader();

      while(rdr.Read())
      {
        int taskId = rdr.GetInt32(0);
        string taskDescription = rdr.GetString(1);
        Task newTask = new Task(taskDescription, taskId);
        AllTasks.Add(newTask);
      }

      conn.Close();

      return AllTasks;
    }

    public void Save()
    {
      SqlConnection conn = DB.Connection();
      SqlDataReader rdr;
      conn.Open();

      SqlCommand cmd = new SqlCommand("INSERT INTO tasks (description) OUTPUT INSERTED.id VALUES (@TaskDescription)", conn);

      SqlParameter testParameter = new SqlParameter();
      testParameter.ParameterName = "@TaskDescription";
      testParameter.Value = this.GetDescription();

      cmd.Parameters.Add(testParameter);

      rdr = cmd.ExecuteReader();

      while(rdr.Read())
      {
        this.id = rdr.GetInt32(0);
      }
      conn.Close();
    }

    public static void DeleteAll()
    {
      SqlConnection conn = DB.Connection();
      conn.Open();
      SqlCommand cmd = new SqlCommand("DELETE FROM tasks;", conn);
      cmd.ExecuteNonQuery();
    }
}

我将DB.Connection定义为 Startup.cs 中的连接字符串:

...
  public class DB
  {
    public static SqlConnection Connection()
    {
      SqlConnection conn = new SqlConnection("Data Source=(localdb)\\mssqllocaldb;Initial Catalog=todo_test;Integrated Security=SSPI;");
      return conn;
    }
  }
...

现在,这是我用来查看它是否有效的测试:

namespace ToDoList
{
  public class ToDoTest : IDisposable
  {
    [Fact]
    public void Test_All()
    {
      //Arrange
      var description = "Wash the dog";
      var description2 = "Water the plants";
      Task testTask = new Task(description);
      testTask.Save();
      Task testTask2 = new Task(description2);
      testTask2.Save();

      //Act
      List<Task> result = Task.All();
      List<Task> testList = new List<Task>{testTask, testTask2};

      //Assert
      Assert.Equal(result, testList);
    }

    public void Dispose()
      {
        Task.DeleteAll();
      }
    }
}

控制台中的输出仅表示测试失败:

ToDoList.ToDoTest.Test_All [FAIL]
  Assert.Equal() Failure
  Expected: List<Task> [Task { }, Task { }]
  Actual:   List<Task> [Task { }, Task { }]

我做了一些控制台日志,每个列表中任务的iddescription都是相同的。

另外,当我测试时:

  List<Task> result = new List<Task>{testTask, testTask2};
  List<Task> testList = new List<Task>{testTask, testTask2};

测试通过。

我不确定如何解决这个问题,看看测试失败的原因。任何想法都会很棒!

1 个答案:

答案 0 :(得分:0)

您需要覆盖该Task.Equals()的{​​{1}}方法才能成功,否则将应用默认引用等于语义。