how ClassData attribute passes data to a test meth

2019-08-12 11:56发布

I am very confused about how [ClassData] attribute works, it's just so weird to me, below is my code:

// I just include basic code, some code such as explicitly implement GetEnumerator() of IEnumerable and Product class are not included for abbreviation

[Serializable]
public class ProductTestData : IEnumerable<object[]>
{
   public IEnumerator<object[]> GetEnumerator()
   {
      yield return new IEnumerable<Product>[] { GetPricesUnder50() };
      yield return new IEnumerable<Product>[] { GetPricesOver50() };
   }

   private IEnumerable<Product> GetPricesUnder50()
   {
      yield return new Product ...//return product's price < 50
   }

   private IEnumerable<Product> GetPricesOver50()
   {
      yield return new Product ...//return product's price > 50
   }
}

and below is the Xunit test class:

[Theory]
[ClassData(typeof(ProductTestData))]
public void Test(Product[] products)
{
   var controller = new HomeController();
   controller.Repository = new ModelCompleteFakeRepository();
   ...
}

and because ClassData only works with IEnumerable<object[]>, so let me re-express ProductTestData for better understanding, so ProductTestData can be considered as:

[Serializable]
public class ProductTestData : IEnumerable<IEnumerable<Product>[]>
{
   ...
}

so when ClassData pass test data to the Test method which received Product[], so somehow. ClassData must use foreach to iterate ProductTestData to get individual IEnumerable<Product>[], and I'm stuck in here.

Q1- Does ClassData uses foreach again on each IEnumerable<Product>[] to get individual IEnumerable<Product> and pass it to the Test method? if yes, it will throw an error if I modify GetEnumerator in ProductTestData as:

public IEnumerator<object[]> GetEnumerator()
{
   yield return new IEnumerable<Product>[] { GetPricesUnder50(), GetPricesOver50() };
}

it produces an error:

The test method expected 1 parameter value, but 2 parameter values were provided.

Q2- so I guess ClassData doesn't do a foreach again on IEnumerable<Product>[], but how ClassData deal with IEnumerable<Product>[] and pass it to the Test method which only requires a parameter of Product[] which is incompatible with IEnumerable<Product>[]?

0条回答
登录 后发表回答