【问题标题】:How to test [TDD] if an specific entry already exists in database如果数据库中已存在特定条目,如何测试 [TDD]
【发布时间】:2019-01-18 18:38:59
【问题描述】:

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

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

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

好吧,TDD 是关于还没有数据项目,而模拟只是用于模拟单个实体(如果我正确理解了这个概念)......所以......如何模拟数据库以便我可以检查是否存在在坚持之前先做leader,甚至创建student或者设置student为leader。还是有更好的方法来做到这一点?

非常感谢!!!

【问题讨论】:

    标签: c# database unit-testing mocking tdd


    【解决方案1】:

    您需要模拟所有内容,包括您的数据库层。如果您通过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;
         }
     }
    

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

    【讨论】:

    • 我正在考虑将此模拟存储库添加到列表而不是数据库中,但我想知道这是否是一种奇怪的方式......谢谢!
    【解决方案2】:

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

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

    例如

    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
         }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-22
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多