Xunit 内联自动数据与 autofixture 问题

Xunit inline auto data with autofixture question

我创建了一个自定义内联自动最小起订量属性,如下所示:

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute()
        : base(() =>{
            var fixture = new Fixture().Customize(new CompositeCustomization(
                new AutoMoqCustomization(),
                new SupportMutableValueTypesCustomization()));
            fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList().ForEach(b => 
            fixture.Behaviors.Remove(b));
            fixture.Behaviors.Add(new OmitOnRecursionBehavior());
            return fixture;}){}
}

public class InlineAutoMoqData : InlineAutoDataAttribute
{
    public InlineAutoMoqData(params object[] objects) : base(new AutoMoqDataAttribute(), objects)
    {

    } 
}

我喜欢自动修复,因为如果我没有通过属性提供测试数据,它会自动为我填充数据。到目前为止,我可以使用内联数据传递空值、字符串、整数等,但如何传递空列表或对象?例如下面的测试方法。请随时修改我的代码以使其正常工作,因为我对单元测试还很陌生。

    [Theory]
    [InlineAutoMoqData(null)]
    public void UpdatePortfolioFiles_InvalidInput_ShouldThrowException(List<MyClass> mytestList, MyTestService sut)
    {
       
        //do something here
       
    }enter code here

您描述的场景听起来像是 MemberAutoDataAttribute 的一个很好的用例。此属性类似于 xUnit 中的 MemberDataAttribute,它应该允许您从静态成员 (field/property/method) 向测试方法提供参数。

目前 MemberAutoDataAttribute 中存在一个错误,它仅提供成员的第一组参数。社区成员 here.

发布了一个解决方法

我会尽快修复该属性。

public static IEnumerable<object[]> TestCases()
{ 
    yield return new object[] { new List<MyClass>() };
    yield return new object[] { new HashSet<MyClass>() };
    yield return new object[] { new LinkedList<MyClass>() };
}

[Theory]
[MemberDomainData(nameof(TestCases))]
public void UpdatePortfolioFiles_InvalidInput_ShouldThrowException(
    IEnumerable<MyClass> mytestList, MyClass sut)
{
    Assert.Empty(mytestList);
    Assert.NotNull(sut);
}

public class MemberDomainData : MemberAutoDataAttribute
{
    public MemberDomainData(string memberName, params object[] parameters)
        : base(new DomainDataAttribute(), memberName, parameters)
    {
    }
}

如果您不想使用解决方法实现,您可以使用声明性语法创建空集合,直到修复出来。

如果这能解决您的问题,请告诉我。

作为建议,您可以将递归省略行为封装在单独的自定义项中。定制意味着小型可重用和可组合。

public class OmitRecursionCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList().ForEach(b =>
        fixture.Behaviors.Remove(b));
        fixture.Behaviors.Add(new OmitOnRecursionBehavior());
    }
}

public class DomainCustomization : CompositeCustomization
{
    public DomainCustomization()
        : base(
            new AutoMoqCustomization(),
            new SupportMutableValueTypesCustomization(),
            new OmitRecursionCustomization())
    {
    }
}

public class DomainDataAttribute : AutoDataAttribute
{
    public DomainDataAttribute()
        : base(() => new Fixture().Customize(new DomainCustomization()))
    {
    }
}