0

我的应用程序中有一个常量,它决定了程序其他部分的操作。我更改此常数以快速轻松地更改程序的操作。

在我的例子中,常数是 abool所以它可以有两个值之一。

我想编写一个测试,以确保无论常量是否设置为 true,我的代码都能正常工作。

例如,假设我的方法是这样的:

public boolean IsEqual(float a, float b) {
    var epsilon = 0.0001;

    if (Constants.Exact) return (Math.Abs(a-b) < epsilon);
    else return (Math.Floor(a) == Math.Floor(b)); 
}

Constants看起来像这样:

public static class Constants {
    /// <summary>
    /// Determines whether an exact comparison should be made, or whether fractional parts should be disregarded.
    /// </summary>
    public const bool Exact = true;
}

并且测试方法是:

[TestMethod]
public void TestEquality() {
    var five = 5;
    var three = 3;

    Assert.True(Equals(five, three));
}

我能想出的解决方案:

  • 像常量不存在一样编写测试,将常量设置为true并运行测试,然后将其设置为 false 并运行测试。不好,因为如果我有 8 个这样的常量,我不想运行测试 256 次。
  • 不要让它成为一个常数。在测试方法内部,首先将常量设置为true,断言,然后为false,再次断言。但是,我首先将其设为常量的原因是为了保证它不会在运行时更改。

我想我真正想要的是一种使其在适当的应用程序方面保持不变的方法,但就测试项目而言不是不变的。

那么我怎样才能使这样的情况起作用呢?

4

3 回答 3

3

创建函数的两个重载,一个带有附加exact参数,另一个使用Exact隐式常量

public bool IsEqual(float a, float b)
{
    return IsEqual(a, b, Constants.Exact);
}

public bool IsEqual(float a, float b, bool exact)
{
    if (exact)
        return a == b;
    else
        return Math.Floor(a) == Math.Floor(b);
}

excat现在您可以在不依赖预定义常量的情况下测试任何值。


更新使用IEquatable<float>(见评论)

IEquatable<T>.Equals只有一个参数。因此我假设Value在这个例子中另一个值被定义为属性

public float Value { get; set; }

#region IEquatable<float> Members

public bool Equals(float other)
{
    return Equals(other, Constants.Exact);
}

#endregion

public bool Equals(float other, bool exact)
{
    if (exact)
        return Value == other;
    else
        return Math.Floor(Value) == Math.Floor(other);
}
于 2012-11-01T13:52:08.333 回答
1

您可以在内部创建常量并通过属性表示它,所以您说

   private const bool _exact = false;

   public bool Exact 
   {  
     get { return _exact };
     set { throw new Exception("Don't set this, you crazy donkey") };
   }

然后为了测试,您可以创建一个继承自常量类但覆盖该Exact属性的类。只要您在父类中通过它的面向公众的名称来调用它,那么您应该能够改变测试中的值并在您的常规实现中保持它不变。

编辑:事实上,如果您的常量都定义在一个类中,那么最好的工作方法是简单地从该类中提取接口,然后您可以在测试时切换实现(或者如果您使用的是 DI某种框架)或简单地使用模拟框架来模拟给定测试所需的任何部分。

于 2012-11-01T13:55:31.543 回答
0

使用枚举而不是常量。这样您就可以防止它被更改为意外的东西,但它是可修改的并且可以扩展更多的值。

于 2012-11-01T13:50:31.883 回答