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

Только начал изучать и писать модульное тестирование день назад, так что это, вероятно, слишком простой вопрос:

У меня есть этот метод в моем классе DBTaskHanlder, для которого я хочу создать какой-то модуль, я смог написать его, когда ModelState недействителен, но теперь для следующего:

public bool CreateTask(ForgotPasswordViewModel fpModel)
{
    if (!ModelState.IsValid)
    {
        return false;
    }

    try
    {
         CreateTaskFromModel(fpModel);
        _dbContext.SaveChanges();
        return true;
    }
    catch (Exception e)
    {
        var issue = e.ToString();
        throw;
    }
}

Этот CreateTaskFromModel метод private, и его задача - создать новую строку в базе данных в таблице. Итак, я хотел проверить, когда вызывается этот метод, создается ли одна новая строка в БД? Правильно ли это тестировать? Как протестировать? Я не думаю, что мы должны ударить и вставить в настоящую базу данных, верно?

   private void CreateTaskFromModel(ForgotPasswordViewModel fpModel)
    {
        var message = _dbContext.Create<Message>();          
        message.MessageType = "TASK".PadLeft(10);
        message.Assigned_User_K = fpModel.SendPasswordRequestTo.Trim();
        message.Assigned_Date = DateTime.Today;
        message.Source_User_K = string.Empty;
        message.Target_File_K = "WEBCFGPHRM";           
        message.Owner_User_K = string.Empty;
        message.Message_K = _keyGenerator.Get10ByteBase36Key();

        _dbContext.Messages.Add(message);
    }

person Community    schedule 16.06.2016    source источник
comment
Тестировать - это правильно, но на данном этапе его не следует называть модульным тестом - лучше было бы называть интеграционный тест. См. stackoverflow.com/questions/10752/   -  person Alexei Levenkov    schedule 16.06.2016


Ответы (2)


Я не думаю, что мы должны ударить и вставить в настоящую базу данных, верно?

Да, ты должен. Это не «модульный тест», но ценный тест. По мере того, как вы станете лучше программировать, вы обнаружите, что большинство ваших ошибок находятся на краю вашей программы, где они затрагивают другие вещи, такие как базы данных.

Мне нравится писать CRUD-тесты. Один «метод тестирования», который фактически выполняет серию тестов. Обычно в таком шаблоне:

  1. Создавать
  2. Читается по первичному ключу. Все ли поля настроены правильно?
  3. Читает сборник. Вы получите много записей, есть ли в коллекции только что созданная запись?
  4. Обновлять
  5. Читается по первичному ключу. Поля изменились правильно?
  6. Удалить
  7. Читается по первичному ключу. Ничего не вернули, правда?
  8. Читает сборник. Вы получите много записей, неужели вновь созданная запись больше не находится в коллекции? Остальные записи все еще там?

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

person Jonathan Allen    schedule 16.06.2016
comment
да, я не хочу делать интеграционный тест на этом, кто-то еще в прошлом написал фактический материал для вставки кода, поэтому я просто выполняю чистый модульный тест - person ; 16.06.2016
comment
Класс называется DBTaskHandler. Это хороший признак того, что вам следует тестировать его вместе с базой данных. Не позволяйте себе увлечься мыслью, что модульные тесты в чем-то лучше интеграционных. Несмотря на то, что говорят блоггеры, ни один тест по сути не лучше другого в глобальном смысле. - person Jonathan Allen; 16.06.2016

Как объяснил Джонатан, вы действительно хотите протестировать вставку среди других операций. CRUD-тестирование, на мой взгляд, является очень хорошей проверкой для вашей модели, которая имеет дело с записями базы данных. Но это больше похоже на интеграционное тестирование, чем на модульное тестирование.

Чтобы это был "чистый" модульный тест, вам нужно только протестировать эту конкретную функцию. Итак, как вы тестируете метод, который вставляет db без фактической вставки чего-либо в базу данных (или имея базу данных, если на то пошло)? Имитация предметов! :) Вот вопрос, аналогичный вашему, в котором говорится об этом: Как выполнить модульное тестирование объекта с помощью запросов к базе данных

Также простой поиск в Google поможет вам лучше понять это. Но на самом деле вы имитируете базу данных или любой другой объект, который вам нужен. Для этого вам, вероятно, понадобится какая-то внешняя библиотека, но это не должно быть проблемой, потому что в наши дни насмешки - довольно обычное дело. Некоторые полезные ссылки:

https://msdn.microsoft.com/en-ca/library/ff650441.aspx

https://en.wikipedia.org/wiki/Mock_object

Удачи!

person Roman    schedule 16.06.2016
comment
да, я не хочу делать интеграционный тест на этом, кто-то еще в прошлом написал фактический материал для вставки кода, поэтому я просто выполняю чистый модульный тест - person ; 16.06.2016
comment
Даже с имитацией уровня доступа к данным, как можно избежать выполнения последующей операции чтения, чтобы проверить, действительно ли запись была добавлена ​​в фиктивное хранилище данных? Модульный тест для добавления записи теперь зависит от реализации обратного чтения записей. Как бы вы с этим справились? - person Stack crashed; 03.01.2018
comment
Отвечая на мой собственный комментарий: Возможно, мы просто проверим, что правильные методы интерфейса из репозитория вызывались соответствующее количество раз. Но на самом деле он не проверяет код на наличие дополнительной ошибочной логики. - person Stack crashed; 03.01.2018