如果数据库中已存在特定条目,如何测试 [TDD]

How to test [TDD] if an specific entry already exists in database

我是 C# 的新手,正在学习 TDD。我看到了模拟对象的使用,但几天来我一直在寻找类似我正在做的事情,但我没有找到任何东西。

我对单元测试的第一条规则是不应该存在两个具有相同 属性.

的特定对象

我给你举个例子:假设对象是学生,我不能有两个领导者,所以,在我的新手心目中,我的测试就像创建两个学生并将他们设置为领导者。当我坚持第二个时,我会采取例外,或类似的方式。

好吧,TDD 还没有数据项目,模拟只是为了模拟单个实体(如果我理解正确的话)...所以...如何模拟数据库以便我可以检查如果坚持之前有leader,甚至创建学生或将学生设置为leader。或者有更好的方法吗?

非常感谢!!!

您需要模拟所有内容,包括您的数据库层。如果您通过 IRepository 实例访问您的数据库,那么您应该创建如下内容:

 public interface IRepository
 {
     List<Student> GetAllStudents();
     void AddStudent(Student student);
     Teacher GetStudentTeacher(int studentId);
 }

 public class MockRepository : IRepository
 {
     public static List<Student> Students { get; set; }
     public static List<Teachers> Teachers { get; set; }

     static MockRepository()
     {
         Students = new List<Student>();
     }

     public List<Student> GetAllStudents()
     {
         return Students.ToList();
     }

     public void AddStudent(Student student)
     {
         Students.Add(student);
     }

     public Teacher GetStudentTeacher(int studentId)
     {
         var student = Students.FirstOrDefault(s => s.Id == studentId);
         if (student != null)
         {
             return Teachers.FirstOrDefault(t => t.Id == student.TeacherId);
         }

         return null;
     }
 }

如果学生已经有老师并且尝试添加第二个老师,上层可以负责抛出异常。

就个人而言,我不会测试数据库实现。我会设置数据库以确保将列设置为唯一并让数据库完成它的工作。

也就是说,如果您想测试您是否在数据库抽象中捕捉到您的独特性。您将设置一个包含多个项目的接口实现,其中两个项目是非唯一的,并确保您抓住它。

例如

public interface IPersonRepository
{
    void AddPerson(Person person);
    IEnumerable<Person> GetPeople();
}

public class PersonService
{
    private static readonly IPersonRepository _repo;

    public PersonService(IPersonRepository repo)
    {
        _repo = repo;
    }

    public void AddPerson(Person person)
    {
        var people = _repo.GetPeople();
        if(people.Select(p=>p.LastName).Contains(person.LastName))
        {
             // person exists
        }
        _repo.AddPerson(person);
    }
}


public class PersonServiceTests
{
     public void ShouldNotAddPersonIfExists()
     {
         var mockRepo = new Mock<IPersonRepository>();
         mockRepo.Set(r => r.GetPeople()).Returns(new[]{new Person(firstName, lastName), new Person(otherName, lastName));

         var service = new PersonService(mockRepo.Object);

         /// try add and check assertions or exceptions thrown
     }
}