如何对使用数据库访问的静态方法进行单元测试?

时间:2014-05-09 04:50:33

标签: c# unit-testing testing linq-to-sql

以下是静态方法示例,例如

public static void UpdateSchedule(int selectedScheduleId)
        {
            using (var dc = new MyDataContext())
            {
                var selectedSchedule = dc.Schedules.SingleOrDefault(p => p.ScheduleId == selectedScheduleId)
                if selectedSchedule != null)
                {
                    selectedSchedule.Name = name;
                    //and update other properties...
                }
                dc.SubmitChanges();
            }
        }

那么测试这样的方法的正确方法是什么?有没有办法避免调用新的MyDataContext(),因为它可能会增加单元测试的执行时间。

另外,我在VS2012中使用MsTest测试框架。

2 个答案:

答案 0 :(得分:3)

静态功能主要干扰测试:

  1. 难以(有时不可能)从消费者中取代
  2. 倾向于拥有“隐藏”的依赖关系
  3. 由于您要测试函数本身,因此编号1不是问题。但是,数字2是有问题的,因为MyDataContext类的静态函数是tightly coupled

    如果要在没有MyDataContext的情况下测试静态函数(即隔离),则需要introduce a code seam。这需要一些重构工作,但我们可以相当轻松地完成。

    考虑您是否有以下额外方法:

        public static void UpdateScheduleWithContext(int selectedScheduleId, IDataContext dc)
        {
            var selectedSchedule = dc.Schedules.SingleOrDefault(p => p.ScheduleId == selectedScheduleId)
            if selectedSchedule != null)
            {
                selectedSchedule.Name = name;
                //and update other properties...
            }
            dc.SubmitChanges();
        }
    

    这个新功能为消费者(即测试)提供了为数据上下文提供测试加倍的能力。这是接缝

    但是,显然,您并不希望所有消费者都明确提供数据上下文(这就是您开始使用原始静态函数的原因)。所以你可以保留这个功能,然后修改它:

        public static void UpdateSchedule(int selectedScheduleId)
        {
            using (var dc = new MyDataContext())
            {
                UpdateScheduleWithDataContext(selectedScheduleId, dc);
            }
        }
    

    如果你没有这样的接缝,就不可能单独测试这个功能。因此,集成测试将是您所希望的最佳选择。

答案 1 :(得分:1)

正如Simon Whitehead所说,不可能对静态方法和对象进行有效的单元测试。但是,使用Visual Studio中的单元测试框架,您可以创建一个有效的集成测试“单元测试”功能。告诉Visual Studio为UpdateSchedule生成单元测试,然后修改生成的函数以设置程序的环境/状态,以便UpdateSchedule方法可以执行(创建数据库连接,实例化类等)。这包括确保您的数据库有要更新的记录。

完成后,您可以按照与单元测试相同的方式执行集成测试。