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()))
{
}
}
我创建了一个自定义内联自动最小起订量属性,如下所示:
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()))
{
}
}