10
[Test]
public void testMultiplication()
{
    var five=new Dollar(5);
    Assert.AreEqual(new Dollar(10), five.times(2));
    Assert.AreEqual(new Dollar(15), five.times(3));
}

ドルクラス

public class Dollar
{
    private int amount;

    public Dollar(int amount)
    {
        this.amount = amount;
    }

    public Dollar times(int multiplier)
    {
        return new Dollar(amount * multiplier);
    }

    public bool equals(Object theObject)
    {
       Dollar dollar = (Dollar) theObject;

       return amount == dollar.amount;
    }
}

オンライン Assert.AreEqual(new Dollar(10), five.times(2)); テストはエラーで失敗します:

予想: TDDbooks.Dollar

しかし、だった: TDDbooks.Dollar

4

5 に答える 5

11

メソッドはAssert.AreEqualsメソッドを使用してEquals等価性をテストします。Object.Equals型をオーバーライドする代わりに、.Net オブジェクトの等価性に関与しないDollar新しいメソッドを定義するだけです。equalsしたがって、それは使用されず、テストは失敗する参照の等価性を使用します。これを修正するには、Object.Equalsメソッドをオーバーライドする必要があります

public override bool Equals(object obj) { 
  Dollar other = obj as Dollar;
  if (other == null) {
    return false;
  }

  return amount == other.amount;
}
于 2012-10-22T15:15:41.330 に答える
5

NUnit は、オブジェクトの文字列表現を表示します。便利な出力を得るには、クラスToStringのメソッドをオーバーライドする必要があります。Dollar

public override string ToString()
{
   return "$" + amount;
}

出力は次のようになります。

Expected: $10 
But was: $10

次の問題はドル比較です。NUnit はEqualsメソッドを呼び出してオブジェクトを比較します ( ではありませんequalsが、EqualsKent Beck は例で Java を使用しています。C# では、メソッドに Pascal の名前を付けています)。メソッドのデフォルトの実装はEquals、オブジェクトが同じ参照を持つ場合に true を返します。ただし、メソッドでは、クラスTimesの新しいインスタンスを作成します。Dollarこれを修正するには、Equals金額フィールドを比較するようにメソッドの実装を変更する必要があります。

public override bool Equals(object obj)
{ 
  Dollar other = obj as Dollar;
  if (other == null)
    return false;  

  return amount == other.amount;
}

overrideまた、基本クラスの機能をオーバーライドするにはキーワードを使用する必要があることに注意してください。もう1つ-Equals機能をオーバーライドする場合は、GetHashCodeメソッドをオーバーライドする必要があります。あなたの場合、次のようなもので問題ありません。

public override int GetHashCode()
{
  return amount.GetHashCode();
}
于 2012-10-22T15:18:29.143 に答える
0

あなたが主張しているnew Dollar(10)のは、それが返されるものと同じオブジェクトであるということですfive.times(2)が、これは真実ではありません。

そのようにアサートしたい場合は、Dollar クラスの Equals メソッドを次のようにオーバーロードする必要があります。

 public override bool Equals(Object obj)
 {
     if (obj is Dollar)
     {
         return this.Amount == ((Dollar)obj).Amount;
     }
     return false;
 }

メソッドでoverrideキーワードを使用していません。Equals

于 2012-10-22T15:23:39.120 に答える
0

いくつかのことがあります:

  1. equals基本クラスのメソッドをオーバーライドする代わりに、新しいメソッドを定義しましたEquals。オーバーライドに切り替えると、NUnit がメソッドを呼び出します。
  2. NUnit は、その を使用してオブジェクトを出力します。ToStringToStringのデフォルトの実装では、単にクラス名を出力します。金額を出力するようにオーバーライドToStringすると、アサーション メッセージがより意味のあるものになります。
于 2012-10-22T15:17:52.003 に答える
0

最良の解決策はすでに何人かの人々によって与えられていますが、他の状況で機能する可能性のある代替手段があります. amount次のように、フィールドにゲッターを追加する必要があります。

public int Amount { get { return amount; } }

そして、単体テストを実行すると、次のようになります。

Assert.AreEqual(10, five.times(2).Amount);

intこれで、を別のと比較していますint。別の方法として、変数を public にすることもできますが、amountカプセル化は壊れます。この場合、明らかにこのEquals方法を適切に使用する方が良い方法ですが、状況によっては、これが望ましい場合もあります。

于 2012-10-22T16:38:47.380 に答える