我面临一个有趣的问题。我发现AutoDataAttribute可用于最小化" Arrange"测试的一部分(通过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)
{
(...)
}
现在我想使用这个伟大的功能和将自己的数据注入到这个理论中:
[Theory, AutoMoqData, MemberData("Data")]
public void ExtractPayments_EmptyInvoiceNumber_IgnoresRecordsWithEmptyInvoiceNumber(
[Frozen]Mock<IExcelDatasource> xls,
SunSystemExcelDatasource sut,
List<Row> rows,
int expectedCount)
{
(...)
}
问题:AutoData属性会为我生成随机数据。我发现的唯一方法是摆脱AutoData属性并使用MemberData。如果我这样做,我需要自己处理对象实例化:)...
有没有办法传递我的课程和一些&#34;硬编码&#34;数据同时?
谢谢你, SEB
答案 0 :(得分:6)
有没有办法传递我的课程和一些&#34;硬编码&#34;数据同时?
这样做的一种方法是通过属性提供一些内联值,并让AutoFixture填充其余部分。
[Theory, InlineAutoMoqData(3)]
public void ExtractPayments_EmptyInvoiceNumber_IgnoresRecordsWithEmptyInvoiceNumber(
int expectedCount,
[Frozen]Mock<IExcelDatasource> xls,
SunSystemExcelDatasource sut,
List<Row> rows)
{
// expectedCount is 3.
}
请注意,我必须移动expectedCount
才能成为第一个参数,并使用定义为的自定义InlineAutoMoqData
属性:
internal class AutoMoqDataAttribute : AutoDataAttribute
{
internal AutoMoqDataAttribute()
: base(new Fixture().Customize(new AutoMoqCustomization()))
{
}
}
internal class InlineAutoMoqDataAttribute : CompositeDataAttribute
{
internal InlineAutoMoqDataAttribute(params object[] values)
: base(
new DataAttribute[] {
new InlineDataAttribute(values),
new AutoMoqDataAttribute() })
{
}
}
答案 1 :(得分:1)
您必须创建自己的自定义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;
}
如果要启用Moq,请将其扩展为
/// <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)
{
}
}