2

我们有一个类,它看起来像下面这样:

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

4 回答 4

8

对于您的确切情况,我可能有一个 appSettings 变量来确定相应服务器的超时时间(dev/whatever)。

但总的来说,#if DEBUG在适当的时候使用该指令是非常合适的。但一般来说,你只会在你真正想要阻止在其中编译给定代码时使用它,在发布模式下。

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

于 2009-09-11T03:13:42.060 回答
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);
}
于 2009-09-11T03:17:00.600 回答
0

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

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

于 2009-09-11T03:12:45.663 回答
0
#if DEBUG
const int TIMEOUT = 60;
#else
const int TIMEOUT = 600;
#endif

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

于 2009-09-11T03:14:58.470 回答