[英]How to combine PropertyData and AutoNSubstituteData attributes in xunit/autofixture?
我正在使用[AutoNSubstituteData]
属性,该属性已在此处发布:
AutoFixture,xUnit.net和Auto Mocking
我想将它与xunit扩展的[PropertyData("")]
属性结合起来。
这是我的测试:
public static IEnumerable<string[]> InvalidInvariant
{
get
{
yield return new string[] { null };
yield return new [] { string.Empty };
yield return new [] { " " };
}
}
[Theory, AutoNSubstituteData, PropertyData("InvalidInvariant")]
public void TestThatGuardsAreTriggeredWhenConnectionStringArgumentIsInvalid(
IDeal deal,
IDbConnection conn,
IDb db,
ISender sender,
string invalidConnString,
string query)
{
deal.Init.Group.Returns(Group.A);
deal.Aggr.Group.Returns(Group.A);
deal.Product.Commodity.Returns(Product.Commodity.E);
var sut = new Handler(db, sender);
Assert.Throws<ArgumentException>(() =>
sut.HandleDeal(deal, conn, invalidConnString, query));
}
有没有办法组合这些属性或获得所需的功能(模拟一切,除了invalidConnstring
,应该用属性数据填充)?
[Theory]
属性通过查找一个或多个'数据源属性'来工作; 例如
[InlineData]
[PropertyData]
[ClassData]
[AutoData]
属性只是另一个这样的属性,派生的[AutoNSubstituteData]
属性也是如此。
可以将相同的[Theory]
添加多个“数据源属性”,这可以通过[InlineData]
属性的惯用使用来[InlineData]
:
[Theory]
[InlineData("foo")]
[InlineData("bar")]
[InlineData("baz")]
public void MyTest(string text)
这产生了三个测试用例。
也可以组合[PropertyData]
和[AutoData]
,但它可能不会做你想做的事情 。 这个:
[Theory]
[AutoNSubstituteData]
[PropertyData("InvalidInvariant")]
public void MyTest(/* parameters go here */)
将导致1 + n个测试用例:
[AutoNSubstituteData]
1个测试用例 InvalidInvariant
属性的n个测试用例 这两个属性对彼此一无所知,所以你不能将它们组合起来,因为它们彼此了解。
但是,当您实现一个属性时,您可以编写您想要的任何代码,包括使用Fixture
实例,那么为什么不这样做呢?
public static IEnumerable<string[]> InvalidInvariant
{
get
{
var fixture = new Fixture().Customize(new MyConventions());
// use fixture to yield values...,
// using the occasional hard-coded test value
}
}
另一种选择是使用来自InlineAutoDataAttribute
派生,这将使您能够像这样编写测试用例:
[Theory]
[MyInlineAutoData("foo")]
[MyInlineAutoData("bar")]
[MyInlineAutoData("baz")]
public void MyTest(string text, string someOtherText, int number, Guid id)
这将导致第一个参数( text
)用属性中的常量填充,而其余参数由AutoFixture填充。
从理论上讲,您也可以使用CompositeDataAttribute
[AutoData]
和[PropertyData]
属性,但它可能无法按照您的喜好工作 。
最后,您可以考虑使用Exude进行真正的一流参数化测试。
有两种方法可以做到这一点:
选项1 - 使用AutoFixture.Xunit和CompositeDataAttribute类:
internal class AutoNSubstituteDataAttribute : AutoDataAttribute
{
internal AutoNSubstituteDataAttribute()
: base(new Fixture().Customize(new AutoNSubstituteCustomization()))
{
}
}
internal class AutoNSubstitutePropertyDataAttribute : CompositeDataAttribute
{
internal AutoNSubstitutePropertyDataAttribute(string propertyName)
: base(
new DataAttribute[] {
new PropertyDataAttribute(propertyName),
new AutoNSubstituteDataAttribute() })
{
}
}
定义测试用例如下:
public class Scenario
{
public static IEnumerable<object[]> InvalidInvariantCase1
{
get
{
yield return new string[] { null };
}
}
public static IEnumerable<object[]> InvalidInvariantCase2
{
get
{
yield return new string[] { string.Empty };
}
}
public static IEnumerable<object[]> InvalidInvariantCase3
{
get
{
yield return new string[] { " " };
}
}
}
然后将参数化测试声明为:
public class Scenarios
{
[Theory]
[AutoNSubstitutePropertyData("InvalidInvariantCase1")]
[AutoNSubstitutePropertyData("InvalidInvariantCase2")]
[AutoNSubstitutePropertyData("InvalidInvariantCase3")]
public void AParameterizedTest(
string invalidConnString,
IDeal deal,
IDbConnection conn,
IDb db,
ISender sender,
string query)
{
}
}
请注意,参数化参数invalidConnString
必须在其他参数之前声明 。
选项2 - 使用Exude :
public class Scenario
{
public void AParameterizedTest(
IDeal deal,
IDbConnection conn,
IDb db,
ISender sender,
string invalidConnString,
string query)
{
}
[FirstClassTests]
public static TestCase<Scenario>[] RunAParameterizedTest()
{
var testCases = new []
{
new
{
invalidConnString = (string)null
},
new
{
invalidConnString = string.Empty
},
new
{
invalidConnString = " "
}
};
var fixture = new Fixture()
.Customize(new AutoNSubstituteCustomization());
return testCases
.Select(tc =>
new TestCase<Scenario>(
s => s.AParameterizedTest(
fixture.Create<IDeal>(),
fixture.Create<IDbConnection>(),
fixture.Create<IDb>(),
fixture.Create<ISender>(),
tc.invalidConnString,
fixture.Create<string>())))
.ToArray();
}
}
我已经实现了一个AutoPropertyDataAttribute
,它将xUnit的PropertyDataAttribute
与AutoFixture的AutoDataAttribute
相结合。 我在这里发布了答案。
在您的情况下,您将需要以与从AutoDataAttribute
相同的方式继承属性,除了您传递夹具创建函数而不是实例:
public class AutoNSubPropertyDataAttribute : AutoPropertyDataAttribute
{
public AutoNSubPropertyDataAttribute(string propertyName)
: base(propertyName, () => new Fixture().Customize(new AutoNSubstituteCustomization()))
{
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.