0

私のアプリケーションには、プログラムの他の部分の動作を決定する定数があります。この定数を変更して、プログラムの動作をすばやく簡単に変更します。

私の場合、定数はaboolなので、2つの値のいずれかを持つことができます。

定数が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

関数の2つのオーバーロードを作成します。1つは追加のexactパラメーターを使用し、もう1つは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パラメータは1つだけです。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 に答える