NUnit - модульный тест для проверки транзакции - PullRequest
4 голосов
/ 05 ноября 2019

У меня есть метод, описанный ниже.

Я хотел бы написать два контрольных примера для метода ниже.

1) Успешная транзакция с фиксацией данных

2) Неудачная транзакция с данными отката

Как написать контрольный пример с транзакцией, выполнить ее успешно и неудачно?

public async Task<List<string>> UpdateRequest(MetaData data, List<string> Ids, string requestedBy)
{
    var transaction = await _databaseUtility.CreateTransaction(ConnectionString);

    var messages = new List<string>();

    try
    {
        // Update data
        await _testDal.Update(data, requestedBy, transaction);

        // Update status
        await _sampleDal.UpdateStatus(Ids, requestedBy, transaction);

        // Update saved data
        await _testDal.UpdateSavedData(data, requestedBy, transaction);

        _databaseUtility.CommitTransaction(transaction);
    }
    catch (Exception exception)
    {
        _databaseUtility.RollbackTransaction(transaction);
    }

    return messages;
}

Ответы [ 2 ]

4 голосов
/ 11 ноября 2019

Я думаю, что у вас есть 2 проблемы:

  1. вы используете асинхронное ожидание в модульном тестировании, что означает, что ваш код продолжит работать до того, как что-то действительно будет сделано.
    Вы можете прочитать это https://johnthiriet.com/removing-async-void/#

    Я объясню улов, убедитесь, что await _testDal.Update(data, requestedBy, transaction); Функция Update () возвращает Task.
    И затем вы можете вызвать его с помощью _testDal.Update(data, requestedBy, transaction).Wait() для модульного тестирования.
    и await для вызова вашего обычного кода. это заставит ваш тестовый код ждать, пока обновление не закончится, в то время как обычный код останется как есть.

  2. Я бы использовал службу имитации, такую ​​как NSubstitute https://nsubstitute.github.io/, чтобы смоделироватьответы. служба пересмешки будет использовать отражение для замены интерфейса или класса, который реализует _testDal.
    таким образом, когда вы вызываете функцию Update (), вы можете передавать ей определенные параметры и вызывать исключение при передаче этих параметров в функцию.
    И передать другой набор параметров и вернуть для них правильные сообщения.

Если вы хотите передать другие параметры, вы можете использовать Nunit TestCase(new[] params...) и передать другой набор параметров втакие же юнит-тесты. однако для PassTest и FailTest я бы использовал 2 или более разных тестов.

3 голосов
/ 10 ноября 2019

Этого можно добиться, используя встроенные атрибуты NUnit TestCaseSource и TestCaseData .

[TestCaseSource(nameof(TestCases))]
public List<string> TestTransaction(MetaData data, List<string> ids, string requestedBy)
{
    return testObject.UpdateRequest(data, ids, requestedBy).GetAwaiter().GetResult();
}

public static IEnumerable TestCases
{
    get
    {
        //successful
        yield return new TestCaseData(new MetaData(), new List<string> { "1", "2" }, "test").Returns(new List<string> { "test1", "test2" });
        //failed
        yield return new TestCaseData(null, new List<string> { "1", "2" }, "test").Returns(new List<string> { "test1", "test2" });
        //another failed
        yield return new TestCaseData(new MetaData(), new List<string> { "1", "2" }, string.Empty).Returns(new List<string> { "test1", "test2" });
    }
}

Здесь есть пара моментов

  • Зачем вам List сообщений в методе UpdateRequest? Он только инициализирован, значения не добавляются. В приведенном выше фрагменте кода список сообщений, возвращаемых методом UpdateRequest, просто сопоставляется с ожидаемым результатом, но вы также можете написать здесь любой Assert
  • Неудачная транзакция зависит от вашей логики, которую вы можете передатьневерные данные, которые вызывают исключение, во фрагменте кода, который я использовал, пустой Metadata или requestedBy
  • async Task<List<string>> результат возврата выполняется синхронно, чтобы соответствовать ожидаемому результату возврата List<string>. Источниками асинхронных тестовых примеров являются открытое предложение в NUnit github

Как вариант, вы также можете написать отдельные тесты для успешных и неудачных транзакций и вызвать метод UpdateRequest асинхронно

Вы еще не поделились подробностями о ваших компонентах, и трудно сделать предположение о DAL, но если вы хотите использовать макеты для Update методов, вы можете использовать Moq библиотека и использование Task.FromResult метода для ответов / возвращаемых значений, как описано в этом ответе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...