4

これは現在可能ではないか、それが良い考えでさえあるとは思いませんが、それは私が今考えていたものです。C#プロジェクトの単体テストにMSTestを使用しています。私のテストの1つで、次のことを行います。

MyClass instance;

try
{
    instance = getValue();
}
catch (MyException ex)
{
    Assert.Fail("Caught MyException");
}

instance.doStuff(); // Use of unassigned local variable 'instance'

このコードをコンパイルするにはinstance、宣言時またはcatchブロック内のいずれかに値を割り当てる必要があります。代わりに後で行うこともできreturnますが、コンパイラがこの時点以降は実行を続行できない ことを知っAssert.Failているだけでなく、それでも回避策です。私の知る限りでは、実行がそれを超えて進むことを許可することは決してないので、値なしで使用されることは決してありません。それでは、なぜそれに値を割り当てなければならないのですか?をのようなものに変更すると、コードは正常にコンパイルされます。例外により、初期化されていない状態で使用されるポイントに実行を進めることができないことがわかっているためです。Assert.FailinstanceAssert.Failthrow exinstance

逆に、テストを失敗させたくなく、不確定としてマークした場合はどうなりますか?Assert.Inconclusiveの代わりに行うことができますFail。コンパイラがその後実行が続行されないことを知っていれば便利です。

それでは、実行をどこに進めることができるかについての実行時とコンパイル時の知識の場合ですか?Assert.FailC#が、メンバー(この場合はメンバーが戻った後は決して実行を許可しない)を言う方法があるのは合理的でしょうか?多分それはメソッド属性の形であるかもしれません。これはコンパイラにとって有用ですか、それとも不必要な複雑さですか?

外部ユニットテスト

人々はこれがユニットテストを書くためのばかげた方法であると[正当に]指摘しているので、ユニットテストの領域外で私の質問を考えてみてください。

MyClass instance;

if (badThings)
{
    someMethodThatWillNeverReturn();
}
else
{
    instance = new MyClass();
}

instance.doStuff();

ここでは、への呼び出しを例外のスローに置き換えることができる可能性がsomeMethodThatWillNeverReturnあります。おそらく、やるべきことがあれば、例外のコンストラクターでそれを行うことができます。

Resharperは知っています

return後にAssert.Failまたはを追加するとAssert.Inconclusive、Resharperreturnは灰色になり、「コードはヒューリスティックに到達不能です」というツールチップが表示されます。

4

5 に答える 5

3

はい、メンバーが正常に完了しないことを示す何かを持っていることは合理的です-つまり、メンバーの後のポイントに到達できないことを主張します。(これは、例外または永久にループしていることが原因である可能性があります。)

あなたは、あなたが間違っている場合のバックアップ計画を考え出すために何かAssert.Fail(CLRまたはコンパイラーにあるかどうかにかかわらず)があることを望みます:誰かが正常に戻るように変更した場合はどうなりますか?コード検証の一部を、正常に返されないことを確認したものにする必要があるかもしれません。

マイクロソフトの誰かからこのアイデアについてのブログ投稿があると思います...私はそれを見つけることができるかどうかを確認します。

それを表現するための構文に関しては、属性は明白なアイデアですが、私は「決して」の戻りタイプのアイデアが非常に好きです。明らかに、それは既存の「決して」タイプと衝突する可能性がありますが、ちょっと...

その有用性の観点から:明らかな回避策は、ステートメントの直後に例外をスローすることですが、それを行わなければならないのは確かに面倒です。(これを書いているメソッドがreturn型を持っている場合、無意味な戻り値を指定する必要がないことを意味するので、一般的にreturnよりも優れています-また、すべてのoutパラメーターが割り当てられた値。)したがって、必須ではありません、それは素晴らしいことだと思います。C#チームが限られた予算でできる最も重要なことであるかどうかは別の問題です-エリックを先制するだけです;)

于 2010-03-24T20:27:43.220 に答える
1

throw exAssert.Failtry/catchまたは、この場合はとを完全に削除しAssert.Fail、キャッチされなかった例外を単体テストに失敗させることをお勧めします。

于 2010-03-24T20:36:04.433 に答える
1

私が疑問に思っていることの1つは、手動でコンパイルして実行した場合、ランタイムはこのコードをどのように処理するのでしょうか。私はそれがILコードのエラーをチェックすると信じています、多分それはこの「エラー」もキャッチします...多分そうではありません:)

于 2010-03-24T20:40:32.893 に答える
0

returnAssert.Fail()

于 2010-03-24T20:26:51.203 に答える
0

スローされた例外でFailをアサートしていることを確認したら、テスト全体をtryに移動するか、tryを削除して、スローされた例外を自動的にアサートして失敗させてみませんか。

try
{
    MyClass instance;
    instance = MyClass.getValue();
    instance.doStuff();
}
catch (Exception ex)
{
    Assert.Fail("Caught MyException");
}

... また ...

MyClass instance;
instance = MyClass.getValue();
instance.doStuff();
于 2010-03-24T20:37:38.413 に答える