Autofixture test for invalid constructor parameter

99封情书 提交于 2020-01-02 01:17:15

问题


I have the following class and test. I want to test passing a null value as a parameter to the constructor and are expecting an ArgumentNullException. But since I use the Autofixture's CreateAnonymous method I get a TargetInvocationException instead.

What is the correct way to write those kinds of tests?

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>();
}

回答1:


IMO, Ruben Bartelink's comment is the best answer.

With AutoFixture.Idioms, you can do this instead:

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

The Verify method will provide you with a quite detailed exception message if any constructor argument in any constructor is lacking a Guard Clause.


FWIW, AutoFixture extensively uses Reflection, so I don't consider it a bug that it throws a TargetInvocationException. While it could unwrap all TargetInvocationException instances and rethrow their InnerException properties, that would also mean disposing of (potentially) valuable information (such as the AutoFixture stack trace). I've considered this, but don't want to take AutoFixture in that direction, for exactly that reason. A client can always filter out information, but if information is removed prematurely, no client can get it back.

If you prefer the other approach, it's not too hard to write a helper method that unwraps the exception - perhaps something like this:

public Exception Unwrap(this Exception e)
{
    var tie = e as TargetInvocationException;
    if (tie != null)
        return tie.InnerException;
    return e;
}



回答2:


I came across this while I was searching for something similar. I would like to add that, combined with automoqcustomization and xunit, below code also works and its much cleaner.

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

You just need to create the AutoMoqData attribute as follows.

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

        }
    }


来源:https://stackoverflow.com/questions/15078400/autofixture-test-for-invalid-constructor-parameter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!