Заполнение сложных объектов из листа Excel и передача его в качестве параметра в [Теорию]
Я написал тест ниже, используя mstest, у меня есть лист Excel с примерно 20 строками, тест запускается один раз для каждой строки, а свойство DataRow TestContext заполняется данными для этой строки. Объект TestContext передается в метод PopulateCustomerViaDataSource для объекта customer, который будет заполнен сведениями о клиенте из листа Excel, а затем объект customer передается в веб-метод для импорта данных в другое приложение. Таким образом, в основном все данные для конкретного запуска теста доступны с использованием одного объекта, то есть TestContext, который даже не нужно передавать в тест, поэтому заполнение объектов Customer, например, просто, как круговая диаграмма.
[DataSource("System.Data.Odbc", "Dsn=Excel Files;Driver={Microsoft Excel Driver (*.xls)};dbq=|DataDirectory|\\Data.xls;defaultdir=.;driverid=790;maxbuffersize=2048;pagetimeout=5;readonly=true", "ApVendorImportCreate$", DataAccessMethod.Sequential), TestMethod]
public void CustomerImport_CreateVendor()
{
Customer customer = CustomerImportHelpers.PopulateCustomerViaDataSource(TestContext);
Result result;
using (SomeWebService client = new SomeWebService())
{
result = client.CustomerImport(customer);
}
Assert.IsTrue(result.Success, "Customer import was unsuccessful. Returned error message was \"" + result.Message + "\"");
AssertCustomerInfoSavedCorrectly(customer);
}
Теперь мой вопрос: как мне добиться такого же результата, используя xUnit? Я уже некоторое время пытаюсь, но не понимаю, как правильно, и я гуглю, но не смог найти статью / пост, который бы демонстрировал это конкретно. Все статьи, которые я мог найти о вещах, управляемых данными в xUnit, приводят к тому, что параметры передаются индивидуально, как показано ниже.
public class StringTests3
{
[Theory, ClassData(typeof(IndexOfData))]
public void IndexOf(string input, char letter, int expected)
{
var actual = input.IndexOf(letter);
Assert.Equal(expected, actual);
}
}
public class IndexOfData : IEnumerable<object[]>
{
private readonly List<object[]> _data = new List<object[]>
{
new object[] { "hello world", 'w', 6 },
new object[] { "goodnight moon", 'w', -1 }
};
public IEnumerator<object[]> GetEnumerator()
{ return _data.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator()
{ return GetEnumerator(); }
}
Если бы в моих тестах было только 1 или 2 параметра, это было бы хорошо, но некоторые из них имеют более 20 параметров, которыми должны заполняться объекты Customer, а другие - поэтому я хочу избежать передачи более 20 параметров в метод, как в приведенном выше примере: Либо иметь какой-нибудь TestContext-подобный или другой объект, заполненный данными, которые я могу использовать для заполнения объектов Customer, либо передать объект Customer, уже заполненный данными для строки конкретного теста.
Возможно ли что-либо из вышеперечисленного или есть другой способ сделать это, избегая передачи большого количества параметров? Если нет, вы, ребята, сделали бы этот тест по-другому, и если да, то как?
Я был бы очень признателен за любые рекомендации / советы.
1 ответ
Недавно снова посмотрел на это и понял. Когда я пытался сделать это в первый раз, я был новичком в xUnit и не знал / не понимал, что мне нужно предоставить тестовые данные, используя тип списка.
public class TestDataFixture
{
public static IEnumerable<object[]> TestData
{
get
{
var testCases = new List<object[]>();
var testCase = new object[1];
var testData1 = new TestDataClass()
{
name = "Piet",
surname = "Pompoies"
};
testCase[0] = testData1;
testCases.Add(testCase);
return testCases;
}
}
}
public class DieMatrixReloaded
{
[Theory]
[MemberData("TestData", MemberType = typeof(TestDataFixture))]
public void DieMatrixReloadedTheory(TestDataClass testData)
{
var someVar = testData;
//Assert something here...
}
}