質問
私は多くのプロパティを持っているクラスで作業しています。例えば;
public class Bib
{
public int PartQty { get; set; }
}
今、ユニットテストに。 Xunitテストをしました
[Fact]
public void CanGetAndSetPartQuantity()
{
const int expected = 3;
var target = new Bib() {PartQty = expected};
Assert.Equal(expected, target.PartQty);
}
ここで、私は私がハードコーディングの予想を嫌うのが嫌い= 3.アクセターとミューテーターのこのプロパティをテストする良い方法は何ですか?
解決
制約された非決定的 この種のユニットテストに適しています。代わりにこのように書いてください:
[Fact]
public void CanGetAndSetPartQuantity()
{
const int expected = new Random().Next();
var target = new Bib() {PartQty = expected};
Assert.Equal(expected, target.PartQty);
}
これにより、出力が入力が何であれ、入力を正しく表すことが保証されます。
他のヒント
このプロパティには、整数のゲッター/セッターである以外の動作はないため、本質的にコンパイラが機能したことをテストしているだけです。これにより、基本的にテストに値が追加されません。完全に削除することを検討してください。それはあなたをこの奇妙な状況を軽減するでしょう。 :)
キャプチャしようとしている動作がある場合(たとえば、境界条件が許可されている場合)、それらをテストするだけで、実際には他に何もありません。通常、オブジェクトの一部として利用可能な境界条件の定数があります。これらの定数を使用することを検討してください。
私は、単体テストを「ホワイトボックス」テストにすることを固く信じています。つまり、既知のコーナーケースを使用してテスト入力を選択することが許可されています。この特定のケースでは、自動プロパティを使用して、コンパイラを信頼する場合、テストは不要です。コンパイラが期待どおりに自動プロパティを実装することを信頼できない場合は、書いたようにテストを実行することを信頼することもできません。
とはいえ、より複雑なセッターがある場合、障害の可能性のあるケースに基づいて入力を選択します。いくつかの典型的なケース:
- 検証> = 0を検証するプロパティの負の数
- その他の検証障害
- int.maxvalueのような極端な境界ケースは、セッターのオーバーフローや予期しない動作を時々トリガーすることができます
- 検証を渡すべき任意の価値(あなたがあなたの「良い」ケースにあることを知っている限り、ここで値を選択する方法に関する本当のガイダンスはありません。)
これは役立つはずです...
[Fact]
public void CanGetAndSetPartQuantity()
{
bool fail = false;
int expected = 0;
while (!fail && expected < int.MaxValue)
{
var target = new Bib() {PartQty = expected};
fail = expected != target.PartQty;
expected++;
}
Assert.IsTrue(!fail);
}
私はしばらく前に優れたユニットテスト慣行に関するプレゼンテーションを鳴らしました(申し訳ありませんが、その男の名前は私の脆弱な記憶を逃れました)。彼は、慎重に選択された名前を持つ定数でそのような値を保存することの使用を提唱しました。
あなたの場合、私は次のような名前を使用します
const int SomeRandomValidPartQuantity=3;
これにより、この値を正確に使用する意図を示します。この場合、有効な数量の後になります。
テストは、何らかのユースケースから導き出される必要があります。おもしろいのは、最初にクラスを紹介し、次にTDDに逆になるテストの作成について話したことです。
ユースケースは、コードを通知するテストを通知します。私はあなたのユースケースが「私のAPIのユーザーが呼ばれるプロパティを設定できることを非常に疑っています PartQty
任意の整数に、常に彼らが設定した整数を取り戻す」。 int.MaxValue
と int.MinValue
. 。ただし、これらはめったに現実世界の値ではありません。
現実世界のユースケースは次のように見えるかもしれません:「私のAPIニュースのユーザーは Bib
注入 IFlugleBinder
, 、設定します PartQty
4に、次に電話します Execute
方法。これは電話をかけます Bind
の方法 IFlugleBinder
インスタンス4回。」それがユースケースであれば、テストは非常に異なって見えます。
正直なところ、それはように見えます Bib
ある種のDTOです。私の経験では、ほとんどのDTOは、いくつかの高レベルのユースケースのアーティファクトにすぎません。 APIが提供する関数呼び出しの結果としてDTOが返される場合、インターフェイスを実際に返す必要があり、DTOクラス自体がプライベートである必要があります。その場合、それを明示的にテストする必要はありません(プロパティをテストするだけですメソッド呼び出しから得られる実際の結果の)。同様に、それが露出していない内部DTOの場合、それを公開しないでください。ユーザーが値のバンドルを提供する必要がある場合、APIはインターフェイスを受け入れる必要があります。ユーザーにインターフェイスを実装するクラスを定義したり、このような不変のクラスを提供したりします。
public class Bib : IBib
{
public Bib(int partQty)
{
PartQty = partQty;
}
public int PartQty { get; private set; }
}
その後、コンストラクターがPedanticになりたい場合に機能するかどうかをチェックするテストを作成できますが、それほど重要ではありません。
また、これは「退屈までテスト」カテゴリに該当すると信じていますが、これがテストする価値があると感じている場合は、承認テストは非常に簡単なテスト方法を提供します。添付されているのは、プロパティを確認するための簡単なテストです。
[TestMethod]
[UseReporter(typeof(DiffReporter))]
public void TestMethod1()
{
var fred = new Person{
Age = 35,
FirstName = "fred",
LastName = "Flintstone",
Hair = Color.Black
};
Approvals.Verify(fred.WritePropertiesToString());
}
これにより、次のようなファイルが生成されます。
Person
{
Age: 35
FirstName: fred
LastName: Flintstone
Hair: Color [Black]
}
そのファイルを承認したものに変更するだけで完了です。
拡張方法の使用に注意してください:.writepropertiestostring()
ここに承認テストの基本に関するビデオがあります
mstest: http://www.youtube.com/watch?v=BG8GOMLWQYY
また、このようなAutoFixture AutoData属性を使用することもできます。
[Theory]
[AutoData]
public void CanGetAndSetPartQuantity(int expected)
{
var target = new Bib() {PartQty = expected};
Assert.Equal(expected, target.PartQty);
}