Можно ли использовать директиву отладки #if в C #? - PullRequest
2 голосов
/ 11 сентября 2009

У нас есть класс класс, который выглядит примерно так:

public class Processor
{
    //set timeout in seconds
    private const int TIMEOUT = 600;

    public void Process()
    {
        //DO SOMETHING HERE

        //CHECK TO SEE IF TIMEOUT HAS BEEN HIT
    }
}

По сути, мы хотели бы написать модульный тест, чтобы увидеть, истекает ли время ожидания по истечении указанного количества времени. Очевидно, нам не нужно ждать 10 минут каждый раз, когда мы запускаем тесты. Имея это в виду, мой вопрос:

Как мы можем управлять этим значением, чтобы оно могло составлять, возможно, 10 секунд во время тестирования, но 10 минут в производстве? Есть много очевидных способов сделать это, но я пытаюсь определить, какой путь будет самым чистым. Должны ли мы выставить это как собственность? Включить его в качестве параметра конструктора? Включить это как параметр метода? Использовать директивы компилятора?

Ответы [ 4 ]

8 голосов
/ 11 сентября 2009

Для вашего точного сценария, я бы, вероятно, имел переменную appSettings, которая определяет время ожидания для соответствующего сервера (dev / любой другой).

В общем, вполне уместно использовать директиву #if DEBUG в подходящее время. Но, в общем, вы будете использовать это, только когда вы действительно хотите предотвратить компиляцию данного кода внутри него, в режиме выпуска.

Классическая причина использования такой директивы, по крайней мере с тех пор, как я обнаружил, заключается в том, чтобы прекратить регистрировать операторы, включаемые вообще, в код выпуска. Другой случай, когда вы можете включить определенную общую библиотеку во все проекты, но определенный код в ней не имеет отношения к конкретной платформе, на которую вы развертываете (то есть Compact Framework не имеет класса X, поэтому вы используете директиву для определения режима CF и напишите соответствующий код).

3 голосов
/ 11 сентября 2009

Я бы посмеялся над проверкой кода на тайм-аут.

Если вам что-то похожее на этот код:

public class Processor
{
    //set timeout in seconds
    private const int TIMEOUT = 600;

    public void Process(ITimeout timeout)
    {
        //DO SOMETHING HERE

        timeout.CheckTimeout(TIMEOUT);
    }
}

public interface ITimeout
{
    bool CheckTimeout(int timeout);
}

Вы можете смоделировать метод CheckTimeout.

Вы можете создать фиктивный класс, подобный этому:

public class TimeoutMock : ITimeout
{
    public bool TimeoutExpired;

    public bool CheckTimeout(int timeout)
    {
        return TimeoutExpired;
    }
}

И ваш тест будет выглядеть примерно так:

[TestMethod]
public void TimeoutExpires()
{
    var processor = new Processor();
    var mock = new TimeoutMock();
    mock.TimeoutExpired = true;
    processor.Process(mock);
}
0 голосов
/ 11 сентября 2009
#if DEBUG
const int TIMEOUT = 60;
#else
const int TIMEOUT = 600;
#endif

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

0 голосов
/ 11 сентября 2009

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

Проблема с директивами отладки #if заключается в том, что их слишком легко сломать, если правильный символ не определен. Кроме того, они обычно используются для исключения кода из Release (или для включения кода в Debug); Это усложняет тестирование, и я видел, что они приводят к незначительным ошибкам, когда код с побочным эффектом вызывался в Debug, но не в Release (но не в последнее время).

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