What actually happens
The NumericSequence
[PropertyData]
defines two iterations.
The composition of NumericSequence
[PropertyData]
with [AutoData]
assumes that there is enough data on each iteration.
However, the actual composition is:
1st iteration: [PropertyData], [AutoData]
2nd iteration: [PropertyData], [n/a]
That's why in the 2nd iteration you eventually run out of data.
Composition
The CompositeDataAttribute
respects the LSP in a sense that it is programmed against the base of all data theories, the DataAttribute
class.
(That is, there is no assumption that all attributes are composed with [AutoData]
at the end.)
For that reason, it can't simply jump from the 2nd iteration to the 1st iteration and grab some [AutoData]
values – that would break the LSP.
What you could do
Make the actual composition look like:
1st iteration: [PropertyData], [AutoData]
2nd iteration: [PropertyData], [AutoData]
By defining two properties:
public static IEnumerable<object[]> FirstPropertyData { get {
yield return new object[] { 1 }; } }
public static IEnumerable<object[]> OtherPropertyData { get {
yield return new object[] { 9 }; } }
And then, the original test can be written as:
[Theory]
[AutoPropertyData("FirstPropertyData")]
[AutoPropertyData("OtherPropertyData")]
public void Test(int n1, int n2, int n3)
{
}
The test executes twice and n1
is always supplied by [PropertyData]
while n2
and n3
are always supplied by [AutoData]
.