11

次のクラスとテストがあります。null 値をパラメーターとしてコンストラクターに渡すことをテストしたいのですが、ArgumentNullException. しかし、Autofixture のCreateAnonymousメソッドを使用しているため、TargetInvocationException代わりに が得られます。

この種のテストを書く正しい方法は何ですか?

public sealed class CreateObject : Command {
    // Properties
    public ObjectId[] Ids { get; private set; }
    public ObjectTypeId ObjectType { get; private set; }
    public UserId CreatedBy { get; private set; }

    // Constructor
    public CreateObject(ObjectId[] ids, ObjectTypeId objectType, UserId createdBy) {
      Guard.NotNull(ids, "ids");
      Guard.NotNull(objectType, "objectType");
      Guard.NotNull(createdBy, "createdBy");

      Ids = ids;
      ObjectType = objectType;
      CreatedBy = createdBy;
    }
}

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void constructor_with_null_ids_throw() {
    fixture.Register<ObjectId[]>(() => null);
    fixture.CreateAnonymous<CreateObject>();
}
4

2 に答える 2

13

IMO、Ruben Bartelink のコメントが最良の回答です。

AutoFixture.Idiomsを使用すると、代わりにこれを行うことができます。

var fixture = new Fixture();
var assertion = new GuardClauseAssertion(fixture);
assertion.Verify(typeof(CreateObject).GetConstructors());

Verify メソッドは、コンストラクターのコンストラクター引数に Guard 句がない場合に、非常に詳細な例外メッセージを提供します。


FWIW、AutoFixture は Reflection を広く使用しているため、TargetInvocationException. すべてのインスタンスをラップ解除してそれらのプロパティを再スローすることもできますが、(潜在的に) 価値のある情報 (AutoFixture スタック トレースなど) を破棄することにもなります。私はこれを検討しましたが、まさにその理由で、AutoFixture をその方向に進めたくありません。クライアントはいつでも情報を除外できますが、情報が時期尚早に削除されると、クライアントはそれを取り戻すことができなくなります。TargetInvocationExceptionInnerException

他のアプローチを好む場合は、例外をラップ解除するヘルパー メソッドを作成するのはそれほど難しくありません。おそらく次のようなものです。

public Exception Unwrap(this Exception e)
{
    var tie = e as TargetInvocationException;
    if (tie != null)
        return tie.InnerException;
    return e;
}
于 2013-02-26T07:05:27.167 に答える
0

似たようなものを探していたところ、こちらにたどり着きました。automoqcustomization および xunit と組み合わせて、以下のコードも機能し、はるかにクリーンであることを追加したいと思います。

    [Theory, AutoMoqData]
    public void Constructor_GuardClausesArePresent(GuardClauseAssertion assertion)
    {
        assertion.Verify(typeof(foo).GetConstructors());
    }

次のように AutoMoqData 属性を作成するだけです。

    public class AutoMoqDataAttribute : AutoDataAttribute
    {
        public AutoMoqDataAttribute() : base(() => new Fixture().Customize(new AutoMoqCustomization()))
        {

        }
    }
于 2018-01-06T12:00:20.480 に答える