Can I use #if debug directive in C #?

We have a class that looks something like this:

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
    }
}

      

Essentially, we would like to write a unit test to see if the timeout has elapsed after a specified amount of time. Obviously, we don't want to wait 10 minutes every time we run tests. With this in mind, my question is:

How can we manipulate this value so that it can be maybe 10 seconds during testing, but 10 minutes in production? There are many obvious ways to do this, but I'm trying to figure out which is the cleanest way. Should we expose this as a property? Include it as a constructor parameter? Include it as a method parameter? Use compiler directives?

+2


source to share


4 answers


For your exact scenario, I will probably have an appSettings variable that defines the timeout for the corresponding server (dev / whatever).

In general, however, it makes sense to use the directive #if DEBUG

at the appropriate times. But in general, you will only use this when you want to prevent the given code from being compiled within it, in release mode.



The classic reason to use such a directive, at least from the moment I discovered it, is to stop logging altogether, in the release code. Another is that you can include a specific shared library in all projects, but the specific code in it is not specific to the specific platform you are deploying to (for example, the Compact Framework does not have an X class, so you use a directive to define the CF mode, and write the code accordingly).

+8


source


I would poke fun at this code for checking timeout.

If you have something similar to this code:

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

      

You can mock the CheckTimeout method.



You can create a mock class like this:

public class TimeoutMock : ITimeout
{
    public bool TimeoutExpired;

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

      

And you check it something like this:

[TestMethod]
public void TimeoutExpires()
{
    var processor = new Processor();
    var mock = new TimeoutMock();
    mock.TimeoutExpired = true;
    processor.Process(mock);
}

      

+3


source


Including this parameter as a constructor parameter would be my preference.

The problem with #if debug directives is that they are too easy to break if the correct symbol is not defined. Plus they are usually used to exclude code from Release (or include code in Debug); This makes testing harder, and I've seen them lead to subtle bugs when side-effect code was called in Debug but not in Release (but not recently).

0


source


#if DEBUG
const int TIMEOUT = 60;
#else
const int TIMEOUT = 600;
#endif

      

I don't think that would be a big problem. Somewhere along the line, you will have to use a preprocessor unless you have another way of defining the target of the build at runtime.

0


source







All Articles