Singletons для облегчения модульных тестов в унаследованной кодовой базе. Хорошая идея или нет? - PullRequest
8 голосов
/ 30 ноября 2010

Folks, У меня большая устаревшая кодовая база .Net, и я пытаюсь представить Unit Testing команде. Они хорошие парни, но для них это все ново (если честно, для меня это тоже достаточно ново).

Одна из проблем заключается в том, что база кода интенсивно использует статические классы в System.IO. Существуют обширные внутренние библиотеки статических классов, и классы не записываются в интерфейсы (если только для этого нет реальной причины проектирования). ).

Я разрабатываю стратегию упрощения операций с использованием NUnit и FakeItEasy.

Чтобы устранить зависимости статических классов, я написал инструмент, который генерирует классы-обертки и интерфейсы для существующих статических классов. например В конфигурационном файле я говорю, что я хочу обертки для System.IO Directory & File, инструмент генерирует сборку с кодом вдоль строк. , .

public interface IFile
{
    // All Method signatures taken from System.IO.File
}

internal class File
    : IFile
{
    // All Methods delegate to System.IO.File
}

public interface IIO
{
    IFile File {get;}
    IDirectory Directory {get;}
}

internal class IO
    : IIO
{
    public IFile File {get; private set;}
    public IDirectory Directory {get; private set;}
    public IO()
    {
        File = new File();
        Directory = new Directory();
    }
}


public static class IO
{
    public IIO Instance {get; set;}
    static IO()
    {
        Instance = new IO();
    }
}

Идея состоит в том, что в существующей кодовой базе можно просто обновить поиск / замену и добавить новую ссылку на проект, и что в модульных тестах вы можете назначить объект Mock для IO.Instance.

С одной стороны, я очень доволен этим подходом, он дает чистый и быстрый способ отказаться от непосредственного использования статических классов, плюс дает нам способ макетировать эти статические классы и позволяет тестировать код, который зависит от них. .

С другой стороны, мне кажется, что я заключил сделку с дьяволом, я заменил зависимости на неявных синглетонах зависимостями от явных синглетонов.

Неужели все это пойдет не так, как надо, когда-нибудь в ближайшем будущем, или вы думаете, что это подходящий подход?

1 Ответ

5 голосов
/ 30 ноября 2010

Я бы поступил так же, как вы сделали для устаревшего приложения.Не так много, что вы можете сделать без необходимости рефакторинга больших кусков.Он по-прежнему гибок, поскольку вы можете изменить реализацию через статический класс.

Одной из идей может быть только сделать метод Instance статическим и вместо этого зарегистрировать класс IO в вашем IOC (в виде одиночного).Затем позвольте IOC найти правильную реализацию (которая возвращается статическим методом Instance).

Хорошее введение в контейнеры IoC: http://joelabrahamsson.com/entry/inversion-of-control-introduction-with-examples-in-dotnet

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...