在C#中使用#if debug指令是否可以?

时间:2009-09-11 03:11:36

标签: c# testability

我们有一个类看起来类似于以下类:

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 个答案:

答案 0 :(得分:8)

对于您的确切场景,我可能有一个appSettings变量来确定适当服务器的超时(dev / whatever)。

通常,在适当的时候使用#if DEBUG指令是非常合适的。但一般情况下,只有在实际想要在发布模式下阻止其中给定代码的编译时,才会使用它。

使用这样的指令的一个典型理由,至少在我发现时,是在发布代码中停止记录所包含的语句。另一种情况是,您可能在所有项目中包含某个通用库,但其中的某些代码与您正在部署的给定平台无关(即Compact Framework没有X类,因此您使用该指令来确定CF模式,并相应地编写代码。)

答案 1 :(得分:3)

我会模拟代码检查超时。

如果你有类似的代码:

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

答案 2 :(得分:0)

将它作为构造函数参数包含在我的偏好中。

#if调试指令的问题是,如果没有定义正确的符号,它们很容易破坏。另外,它们通常用于从Release中排除代码(或包含Debug中的代码);它使测试变得更难,我看到它们会导致细微的错误,其中带有副作用的代码在Debug中被调用但在Release中没有被调用(但不是最近)。

答案 3 :(得分:0)

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

我认为这不是一个大问题。除非你有其他方法在运行时定义构建目标,否则你将不得不使用预处理器。