3

またはスローするように単体テストを作成しました。どちらも から派生しています。次に、基本例外の追加に進みましたが、テストがまだ失敗としてマークされていることがわかりました。AnExceptionAnotherExceptionAnExceptionBaseExceptionExpectedExceptionAttribute

テスト名: Call_Should_Throw_If_Device_Is_Not_Ready テスト

...

結果メッセージ: テスト メソッド DiskManagementTests.DiskFreeSpaceTests.Call_Should_Throw_If_Device_Is_Not_Ready が例外 System.IO.FileNotFoundException をスローしましたが、例外 System.IO.IOException が予期されていました。例外メッセージ: System.IO.FileNotFoundException: デバイスの準備ができていません。(HRESULT からの例外: 0x80070015)

この特定のケースでは、HRESULT リターン コードから例外が生成されるため、これは妥当な設計上の決定のように思えます。これにより、どの例外がスローされるかを判断することがほぼ不可能になります。少なくとも、私のテストが想定されているユニットからコードロジックをコピーせずに...テストすることはできません。

私のコード(これはまたはのいずれFileNotFoundかをスローできると思いますDirectoryNotFound):

[TestMethod]
[ExpectedException(typeof(IOException))]
public void Call_Should_Throw_If_Device_Is_Not_Ready()
{
    foreach (DriveInfo drive in DriveInfo.GetDrives().Where(drive => !drive.IsReady))
    {
        DiskFreeSpace diskFreeSpace = DiskManagement.GetDiskFreeSpace(drive.RootDirectory.FullName);
        Assert.Fail("API call did not fail even though the drive reports that it is not ready.");
    }
    Assert.Inconclusive("All drives were ready. Try testing with an empty disc drive.");
}

単体テストの書き方を再考する必要がありますか?

編集

結局、このシナリオはサポートされています。実際にかかったのはAllowDerivedTypes、true に設定することだけでした。

[TestMethod]
[ExpectedException(typeof(IOException), AllowDerivedTypes = true)]
public void Call_Should_Throw_If_Device_Is_Not_Ready()
{
    // ...
}
4

1 に答える 1

1

スローされた例外が属性で定義された例外を継承するかどうかを確認する独自のExpectedException属性を作成できます。

public sealed class MyExpectedException : ExpectedExceptionBaseAttribute
{
    private Type _expectedExceptionBaseType;

    public MyExpectedException(Type expectedExceptionType)
    {
        _expectedExceptionBaseType = expectedExceptionType;
    }

    protected override void Verify(Exception exception)
    {
        Assert.IsNotNull(exception);
        Assert.IsTrue(exception.GetType().IsInstanceOfType(typeof(_expectedExceptionBaseType)) || 
                      exception.GetType().IsSubclassOf(typeof(_expectedExceptionBaseType)));
    }
}

属性をテストに変更します。

[MyExpectedException(typeof(IOException))]
于 2013-07-17T07:22:59.537 に答える