Как проверить список как результат функции в C# - PullRequest
0 голосов
/ 03 августа 2020

Для моей компании я создаю Azure Функции с. NET Core 3.x для создания счетов. Мне нужно рассмотреть другой сценарий ios, и я хочу создать для этого тест.

Я подумал создать функцию, в которой я передаю список строк для счета. В этой функции я должен проверить, есть ли возврат для пользователя: если да, я должен вычесть сумму из текущего счета. Если осталось немного денег для возмещения, мне нужно создать новый счет на возмещение.

public class InvoiceGeneratorResponse
{
    public List<InvoiceGeneratorDetailResponse> Details { get; set; }
    public List<InvoiceGeneratorErrorResponse> Errors { get; set; }
    public List<InvoiceGeneratorNextInvoiceResponse> NextInvoice { get; set; }
}

InvoiceGeneratorResponse - это результат моего класса, где Подробности - это счет list, Errors - это список неполных счетов, а NextInvoice - это список счетов-фактур на возмещение, которые мне нужно создать.

Теперь я хочу создать несколько тестов чтобы проверить каждый сценарий. Для этого мне нужно передать список строк этой функции и проверить результат.

Я думал прочитать список строк из файла json и преобразовать его в список для передачи в функция. Для результата я хочу прочитать другой файл, преобразовать его в список и сравнить список из файла с результатом функции.

Есть ли уже аннотация для чтения файла в тесте? Если да, то в каких рамках? xUnit? nUnit? Есть ли простой способ полностью сравнить два списка в тесте?

Ответы [ 4 ]

2 голосов
/ 03 августа 2020

Есть ли аннотация для чтения файла в тесте? Если да, то в каких рамках? xUnit? nUnit?

Насколько я знаю, это должен быть очень специфический формат, который служит одним целям, но не имеет его для других. Так что, если фреймворк сможет читать JSON, они должны будут его поддерживать, и будут поступать запросы на поддержку XML, Open XML и так далее, так что я могу понять, почему фреймворки тестирования не поддерживают это прямо из коробки.

Однако вы можете использовать атрибуты для предоставления входных параметров для ваших тестов с использованием различных платформ:

MSTest ("управляемый данными tests ") со значениями в атрибутах:

[DataTestMethod]
[DataRow(12,3,4)]
[DataRow(12,2,6)]
[DataRow(12,4,3)]
public void DivideTest(int n, int d, int q)
{
     Assert.AreEqual(q, n / d);
}

NUnit (« параметризованные тесты ») со значениями в массиве:

[TestCaseSource("DivideCases")]
public void DivideTest(int n, int d, int q)
{
    Assert.AreEqual(q, n / d);
}

static object[] DivideCases =
{
    new object[] { 12, 3, 4 },
    new object[] { 12, 2, 6 },
    new object[] { 12, 4, 3 }
};

And xUnit можно расширить до читать данные из файла JSON, указанного в атрибуте и т. Д.

Но в вашем случае, если вы просто хотите подготовить JSON файл, содержащий желаемый результат вашего метода, вы можете прочитать его самостоятельно, используя Newtonsoft. Json и CollectionAssert.AreEqual(expected, actual, comparer), используя свой собственный компаратор для InvoiceGeneratorDetailResponse:

public void Foo_Bars_The_Foo()
{
    // Arrange
    var classUnderTest = ...
    var expectedJson = File.ReadAllText("bar_output.json");
    var expected = JsonConvert.DeserializeObject<List<InvoiceGeneratorDetailResponse>>(expectedJson);
    
    // Act
    var result = classUnderTest...  
    
    // Assert
    var invoiceDetailComparer = new ...
    CollectionAssert.AreEqual(expected, result, invoiceDetailComparer);
}
1 голос
/ 03 августа 2020

Есть ли простой способ полностью сравнить два списка в тесте?

Да, NUnit предоставляет простой способ - вы можете проверить эквивалентность коллекций:

[Test]
public void ListCompareTest()
{
    List<string> expectedResult = new List<string>
    {
        "someData1", "someData2", "someData3", "someData4"
    };

    // you do something here with your methods and here comes actual result of that work

    List<string> actualResult = new List<string>
    {
        "someData1", "someData2", "someData3", "someData4"
    };

    Assert.That(actualResult, Is.EquivalentTo(expectedResult));
}

Кроме того, для этой цели вы можете использовать настраиваемый компаратор равенства или свою функцию для сравнения результатов:

// custom comparer
Assert.That(actualResult, Is.EquivalentTo(expectedResult)
    .Using(StringComparer.OrdinalIgnoreCase as IComparer));
// custom function to compare the results
Assert.That(actualResult, Is.EquivalentTo(expectedResult)
    .Using<string, string>((left, right) => Regex.IsMatch(left, right)));
0 голосов
/ 05 августа 2020

Я нашел решение своего вопроса. Я видел, как читать данные из файла , но это не работает для сложных объектов, таких как, в моем случае, счет-фактура. Я обнаружил, что FluentAssertions имеет специальный пакет c для сравнения файлов json. вызывается FluentAsertions.Json.

FluentAsertions.Json

Based on that, I have created my tests as following:

[Test]
public void Check_Result_With_One_Organization_Simple()
{
    List invoice = new FileService>()
                                         .GetData("Data\\invoice-in-1.json");
    InvoiceGeneratorResponse expected = new FileService()
                                         .GetData("Data\\invoice-out-1.json");

    InvoiceGeneratorResponse response = _service.GenerateAndSaveInvoices(invoice);

    JToken jExpected = JToken.Parse(JsonConvert.SerializeObject(expected));
    JToken jResponse = JToken.Parse(JsonConvert.SerializeObject(response));

    jResponse.Should().BeEquivalentTo(jExpected);

    Assert.AreEqual(expected.NumberOfErrors, response.NumberOfErrors);
    Assert.AreEqual(expected.NumberOfInvoices, response.NumberOfInvoices);
    Assert.AreEqual(expected.NumberOfOrganisations, response.NumberOfOrganisations);

    Assert.AreEqual(expected.Total, response.Total);
    Assert.AreEqual(expected.TotalAmount, response.TotalAmount);
    Assert.AreEqual(expected.TotalTaxes, response.TotalTaxes);
}

FileService is my simple class to read a json file from the filesystem and returns an object in T.

/// 
/// Class FileService.
/// 
///  publi c class FileService где T: class {/// /// Получает данные. ///  /// Имя файла.  /// T.  publi c T GetData (строка имени файла) {var dataset Json = File.ReadAllText (имя файла); var dataset = JsonConvert.DeserializeObject (набор данных Json); вернуть набор данных; }} 

Маг c находится в этой строке

jResponse.Should().BeEquivalentTo(jExpected);

Здесь FluentAsertions. Json проверяет файлы json и сообщает вам, если эти файлы и именно та же структура, а если нет, дает те же сведения.

FluentAsertions. Json

0 голосов
/ 03 августа 2020

Модульные тесты должны быть быстрыми. Итак, вам нужно обнаружить зависимости и смоделировать их.

Для вопроса о файле я бы создал объект Mock (используя Moq с nUnit) для имитации процесса чтения файла. Я считаю, что вы не хотите тестировать часть файловой системы чтения . Вы должны имитировать ввод (файл) и тестировать только свой лог c.

А на вопрос о сравнении двух списков вы можете проверить CollectionAssert , который имеет несколько замечательных функций. Если это не соответствует вашим требованиям, вам необходимо переопределить Equals в своем классе.

...