Unit testing 在XUnit测试中使用AutoData和MemberData属性

Unit testing 在XUnit测试中使用AutoData和MemberData属性,unit-testing,xunit,autofixture,Unit Testing,Xunit,Autofixture,我正面临一个有趣的问题。我发现AutoDataAttribute可以用来最小化测试的“排列”部分(通过ctor传递的依赖项)。太棒了 例如: public class AutoMoqDataAttribute : AutoDataAttribute { public AutoMoqDataAttribute() : base(new Fixture().Customize(new AutoMoqCustomization())) { } } [Theory, A

我正面临一个有趣的问题。我发现AutoDataAttribute可以用来最小化测试的“排列”部分(通过ctor传递的依赖项)。太棒了

例如:

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

[Theory, AutoMoqData]
public void Process_ValidContext_CallsK2Workflows(
    [Frozen]Mock<IK2Datasource> k2,
    [Frozen]Mock<IAppConfiguration> config,
    PrBatchApproveBroker sut)
{
   (...)
}
公共类automoqdata属性:AutoDataAttribute
{
公共automoqdata属性()
:底座(新夹具()。自定义(新自动moqcustomization())
{ }
}
[理论,自动烟雾数据]
公共作废流程\u ValidContext\u调用SK2工作流(
[冷冻]模拟k2,
[冻结]模拟配置,
PrBatchApproveBroker(sut)
{
(...)
}
现在我想利用这一伟大的功能,将我自己的数据注入这一理论:

[Theory, AutoMoqData, MemberData("Data")]
public void ExtractPayments_EmptyInvoiceNumber_IgnoresRecordsWithEmptyInvoiceNumber(
        [Frozen]Mock<IExcelDatasource> xls,
        SunSystemExcelDatasource sut,
        List<Row> rows,
        int expectedCount)
{
    (...)
}
[理论、自动moqdata、成员数据(“数据”)]
公共无效提取付款\u清空语音号码\u忽略记录私人语音号码(
[冻结]模拟xls,
SUNSYSTEMEXCELDATASURCE sut,
列出行,
int预期计数)
{
(...)
}
问题:AutoData属性将为我生成随机数据。我找到的唯一方法是去掉AutoData属性并使用MemberData。如果我这样做,我需要自己处理对象实例化:)

有没有办法同时传递我的类和一些“硬编码”数据

谢谢你,, 赛博

有没有办法同时传递我的类和一些“硬编码”数据

一种方法是通过属性提供一些内联值,并让AutoFixture填充其余值

[理论,InlineAutoMoqData(3)]
公共无效提取付款\u清空语音号码\u忽略记录私人语音号码(
int预期计数,
[冻结]模拟xls,
SUNSYSTEMEXCELDATASURCE sut,
列表行)
{
//预期计数为3。
}
请注意,我必须移动
expectedCount
作为第一个参数,并使用自定义
InlineAutoMoqData
属性,该属性定义为:

内部类automoqdata属性:AutoDataAttribute
{
内部automoqdata属性()
:底座(新夹具()。自定义(新自动moqcustomization())
{
}
}
内部类InlineAutoMoqDataAttribute:CompositeDataAttribute
{
内部InlineAutoMoqDataAttribute(参数对象[]值)
:基本(
新数据属性[]{
新的InlineDataAttribute(值),
新的AutoMoqDataAttribute()})
{
}
}

有关其他一些示例,请参见post和one。

您必须创建自己的自定义DataAttribute。这就是你写作的方式

/// <summary>
/// Helper DataAttribute to use the regular xUnit based DataAttributes with AutoFixture and Mocking capabilities.
/// </summary>
/// <seealso cref="Xunit.Sdk.DataAttribute" />
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class AutoCompositeDataAttribute : DataAttribute
{
    /// <summary>
    /// The attributes
    /// </summary>
    private readonly DataAttribute baseAttribute;

    /// <summary>
    /// The automatic data attribute
    /// </summary>
    private readonly DataAttribute autoDataAttribute;

    /// <summary>
    /// Initializes a new instance of the <see cref="AutoCompositeDataAttribute" /> class.
    /// </summary>
    /// <param name="baseAttribute">The base attribute.</param>
    /// <param name="autoDataAttribute">The automatic data attribute.</param>
    public AutoCompositeDataAttribute(DataAttribute baseAttribute, DataAttribute autoDataAttribute)
    {
        this.baseAttribute = baseAttribute;
        this.autoDataAttribute = autoDataAttribute;
    }

    /// <summary>
    /// Returns the data to be used to test the theory.
    /// </summary>
    /// <param name="testMethod">The method that is being tested</param>
    /// <returns>
    /// One or more sets of theory data. Each invocation of the test method
    /// is represented by a single object array.
    /// </returns>
    public override IEnumerable<object[]> GetData(MethodInfo testMethod)
    {
        if (testMethod == null)
        {
            throw new ArgumentNullException(nameof(testMethod));
        }

        var data = this.baseAttribute.GetData(testMethod);

        foreach (var datum in data)
        {
            var autoData = this.autoDataAttribute.GetData(testMethod).ToArray()[0];

            for (var i = 0; i < datum.Length; i++)
            {
                autoData[i] = datum[i];
            }

            yield return autoData;
        }
    }
}



/// <summary>
/// Member auto data implementation based on InlineAutoDataAttribute and MemberData
/// </summary>
/// <seealso cref="Ploeh.AutoFixture.Xunit2.CompositeDataAttribute" />
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MemberAutoDataAttribute : AutoCompositeDataAttribute
{
    /// <summary>
    /// The automatic data attribute
    /// </summary>
    private readonly AutoDataAttribute autoDataAttribute;

    /// <summary>
    /// Initializes a new instance of the <see cref="MemberAutoDataAttribute" /> class.
    /// </summary>
    /// <param name="memberName">Name of the member.</param>
    /// <param name="parameters">The parameters.</param>
    public MemberAutoDataAttribute(string memberName, params object[] parameters)
        : this(new AutoDataAttribute(), memberName, parameters)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="MemberAutoDataAttribute" /> class.
    /// </summary>
    /// <param name="autoDataAttribute">The automatic data attribute.</param>
    /// <param name="memberName">Name of the member.</param>
    /// <param name="parameters">The parameters.</param>
    public MemberAutoDataAttribute(AutoDataAttribute autoDataAttribute, string memberName, params object[] parameters)
        : base((DataAttribute)new MemberDataAttribute(memberName, parameters), (DataAttribute)autoDataAttribute)
    {
        this.autoDataAttribute = autoDataAttribute;
    }

    /// <summary>
    /// Gets the automatic data attribute.
    /// </summary>
    /// <value>
    /// The automatic data attribute.
    /// </value>
    public AutoDataAttribute AutoDataAttribute => this.autoDataAttribute;
}
//
///Helper DataAttribute使用常规的基于xUnit的DataAttributes,并具有自动固定和模拟功能。
/// 
/// 
[AttributeUsage(AttributeTargets.Method,AllowMultiple=true)]
公共类AutoCompositeDataAttribute:DataAttribute
{
/// 
///属性
/// 
私有只读数据属性baseAttribute;
/// 
///自动数据属性
/// 
私有只读数据属性autoDataAttribute;
/// 
///初始化类的新实例。
/// 
///基本属性。
///自动数据属性。
公共AutoCompositeDataAttribute(DataAttribute baseAttribute、DataAttribute autoDataAttribute)
{
this.baseAttribute=baseAttribute;
this.autoDataAttribute=autoDataAttribute;
}
/// 
///返回用于测试理论的数据。
/// 
///正在测试的方法
/// 
///一组或多组理论数据。每次调用测试方法
///由单个对象数组表示。
/// 
公共重写IEnumerable GetData(MethodInfo testMethod)
{
if(testMethod==null)
{
抛出新ArgumentNullException(nameof(testMethod));
}
var data=this.baseAttribute.GetData(testMethod);
foreach(数据中的var数据)
{
var autoData=this.autoDataAttribute.GetData(testMethod.ToArray()[0];
对于(变量i=0;ithis.AutoDataAttribute;
}
如果您想启用最小起订量,那么扩展它以获得最大起订量

/// <summary>
/// The member auto moq data attribute.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MemberAutoMoqDataAttribute : MemberAutoDataAttribute
{
    /// <summary>
    /// Initializes a new instance of the <see cref="MemberAutoMoqDataAttribute"/> class.
    /// </summary>
    /// <param name="memberName">Name of the member.</param>
    /// <param name="parameters">The parameters.</param>
    public MemberAutoMoqDataAttribute(string memberName, params object[] parameters)
        : base(new AutoMoqDataAttribute(), memberName, parameters)
    {
    }
}
//
///成员自动最小起订量数据属性。
/// 
[AttributeUsage(AttributeTargets.Method,AllowMultiple=true)]
公共类MemberAutoMoqDataAttribute:MemberAutoDataAttribute
{
/// 
///初始化类的新实例。
/// 
///成员的姓名。
///参数。
public MemberAutoMoqDataAttribute(字符串memberName,参数对象[]参数)
:base(新的AutoMoqDataAttribute(),memberName,参数)
{
}
}
我不知道。从我所知道的