Вопрос

Here's the sample static method, say

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();
            }
        }

So what would be the correct approach to test on methods like this? Is there a way to avoid calling new MyDataContext() as it might increase the execution time of the unit test.

Also, I am using MsTest test framework in VS2012.

Это было полезно?

Решение

Static functions interfere with testing primarily because they:

  1. Are difficult (sometimes impossible) to substitute from within a consumer
  2. Tend to have "hidden" dependencies

Since you want to test the function itself, number 1 isn't an issue. However, number 2 is problematic because the static function is tightly coupled to the MyDataContext class.

If you want to test the static function without MyDataContext (that is, in isolation) you need to introduce a code seam. This requires some refactoring work, but we can do it fairly painlessly.

Consider if you had the following additional method:

    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();
    }

This new function gives the consumer (i.e., the test) the ability to supply a test double for the data context. This is the seam.

Obviously, though, you don't want all consumers to explicitly provide a data context (which is why you had the original static function to begin with). So you can keep that function around, and just modify it:

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

If you don't have a seam like this, it will be impossible to test the function in isolation. As a result, an integration test would be the best you could hope for.

Другие советы

As Simon Whitehead said, it is impossible to do effective unit testing on static methods and objects. However, using the unit test framework in Visual Studio, you can create a 'unit test' function that is effectively a integration test. Tell Visual Studio to generate a Unit Test for UpdateSchedule, and then modify the function generated to set up the environment/state of the program such that the UpdateSchedule method can execute (create a database connection, instantiate classes, etc.). This includes ensuring that your database has records to update.

Once that is done, you can execute your integration test in the same manner that you would a unit test.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top