TDD & Design Advice - PullRequest
       4

TDD & Design Advice

0 голосов
/ 19 марта 2012

У меня есть метод, который вызывает Action<string>

public Action<string> DisplayError;

public void MyMethod()
{
  DisplayError("ERROR");
}

. В этом методе я хочу вызвать DisplayError, однако я вижу, что, если DisplayError имеет значение null, он выдаст исключение.

Я могу запустить тест, который доказывает, что он выдаст исключение.

Так что я знаю, что хочу добавить if (DisplayError != null) в мой код, но я чувствую, что этот дизайн как-то не так.Может, тест должен быть другим?

Ответы [ 3 ]

1 голос
/ 19 марта 2012

Это полностью зависит от контекста.

Требуется ли пользователю этого класса установить значение на основе контракта? Тогда следует сгенерировать исключение.

Это необязательно? Тогда ваш чек действителен, но если вы просто по умолчанию установите DisplayError на пустое действие, вы получите похожее поведение

DisplayError = s => {};

Ваш подход также приводит к тому, что пользователь может установить DisplayError на null, и в этом случае только вы можете решить, что действительно. Если вы установите это свойство вместо поля, вы предоставите себе больше возможностей.

_displayError = s => {};

public Action<string> DisplayError
{
   get { return _displayError; }
   set 
   { 
       _displayError = value ?? (s => {}); 
       /* or throw on null */
   }
}
1 голос
/ 19 марта 2012

Вместо того, чтобы делать Action открытым полем, сделайте его свойством или передайте его в метод.После этого вы можете выполнить проверку на нольЯ также сомневаюсь, что вам нужно получить его после установки, поэтому либо:

_displayError = (s) => { throw new ArgumentNullException("Please tell me what to do with this exception!"); };

public Action<string> DisplayError
{
    set 
    {
        if (value == null) { throw new ArgumentNullException("I need this!"); }
        _displayError = value;
    }
}

public void MyMethod()
{
    _displayError("ERROR");
}

, либо:

public void MyMethod(Action<string> displayError)
{
    if (displayError == null) { throw new ArgumentNullException("I need this!"); }
    displayError("ERROR");
}

Первое из них не должно требовать каких-либо изменений кода от ваших потребителей.

Конечно, если вы просто работаете с командой, которая использует ваш код, вам вообще не нужно проверять на ноль .Просто выясните, кто неправильно использует ваш код, и пообщайтесь в чате, чтобы выяснить, в чем заключается недоразумение.Защитное программирование не является хорошей заменой команде, члены которой доверяют друг другу, и проверка на нуль не так эффективна, как наличие четко определенного и простого в использовании интерфейса.

Вам понадобятся 2 теста:

Мой класс:

  • должен позволять потребителю обрабатывать любую ошибку
    • Учитывая, что я собираюсь произвести ошибку по любой причине (установите контекст здесь)
    • Когда я выдаю ошибку (вызов метода, пусть обработчик ошибок установит некоторую переменную)
    • Затем я должен передать ошибку обработчику (проверьте переменную, которая была установлена)
  • должен убедиться, что обработчик ошибок подключен
    • Учитывая, что я могу выдать ошибку (вы можете написать то, что вам нравится здесь, потому что это не имеет значения)
    • Когда потребитель вызываетя без обработчика ошибок (вызовите метод с нулевым обработчиком ошибок)
    • Тогда я должен немедленно попросить потребителя не делать этого (проверьте исключение)
0 голосов
/ 19 марта 2012

Я полагаю, что в разговоре со Стивом Йегги я услышал суть: что-то под мелодию «в то время как статически типизированные языки защищают вас от широкого класса ошибок во время компиляции, они не отменяют необходимостьпроверка на ноль. '

Я нахожу это совершенно нормальным.

Я просто пью свой утренний кофе, поэтому дайте мне знать, если я полностью пропустил отметку.

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