Заполнение сложных объектов из листа 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...
    }
}
Другие вопросы по тегам