Unit testing 在XUnit测试中使用AutoData和MemberData属性
我正面临一个有趣的问题。我发现AutoDataAttribute可以用来最小化测试的“排列”部分(通过ctor传递的依赖项)。太棒了 例如: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
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,参数)
{
}
}
我不知道。从我所知道的