Модульное тестирование: добавление записи в базу данных - PullRequest
2 голосов
/ 19 мая 2011

Как я могу написать модульный тест, который проверит способность метода добавлять запись в базу данных?В настоящее время у меня есть следующее:

[TestMethod]
public void AddUserTest()
{
    Boolean expected = true;
    Boolean result = UserManager.AddUser(test);

    Assert.AreEqual(expected, result);
}

Это работает надлежащим образом, если я тестирую только возможность добавления записи в базу данных (не беспокоясь, если запись уже существует).Однако я не уверен, как создать тест таким образом, чтобы он все равно проходил, если отправка не удалась из-за существующей записи.

Если это имеет значение, я использую LINQ to SQL длямоя база данных транзакций.Из того, что я мог собрать в документации MSDN, DataContext.SubmitChanges() не имеет возвращаемого значения, поэтому я также не уверен, как определить, была ли конкретная транзакция успешной.

Я буду продолжать просматривать документацию.Perhaps DataContext.SubmitChanges() выдает исключение при конфликте записей или другом сбое, которое я мог бы отловить в модульном тесте?

Ответы [ 4 ]

6 голосов
/ 19 мая 2011

Как только появляется внешний агент (например, файловая система, база данных и т. Д.), Это действительно интеграционный тест.

Ваш AddUserTest выше имеет недостатки: метод AddUser может вернуть true не добавляя ничего или не добавляя это правильно и все еще возвращайте true!В этом случае вы ничего точно не проверили.

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

1 голос
/ 19 мая 2011

Я согласен с Митчем (это действительно интеграционный тест).

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

[TestMethod()]
[ExpectedException(typeof(System.Data.Linq.DuplicateKeyException))]
public static void MyTest()
{
    ....
}

Если вам нужно проверить сообщение об исключении, существует полезная перегрузка, которая позволяет вам указать ожидаемую строку (см.http://msdn.microsoft.com/en-US/library/ms243315.aspx)

public ExpectedExceptionAttribute(
    Type exceptionType,
    string noExceptionMessage
)

, которые будут использоваться

[ExpectedException(typeof(DuplicateKeyException), "Something went wrong")]
0 голосов
/ 19 мая 2011

Вы получите исключение нарушения первичного ключа, если запись существует. Вы можете избежать исключения, изменив UserManager.AddUser для явной проверки этого случая, выбрав запись из базы данных перед вставкой (см. Any () или SingleOrDefault () Linq). Если запись возвращается, явно вернуть false.

Или оберните весь код в AddUser в блок try / catch. Верните ложь в улове.

Черт, делай оба.

Кроме того, почему бы не проверить тестовую базу данных, чтобы увидеть, была ли запись вставлена ​​в тест? Я бы не взял слово тестируемого метода для успеха / неудачи, разве вы не должны это проверить?

Юнит-тестирование с реальной базой данных не поощряется пуристами юнит-тестирования. На самом деле мы unit тестируем большую часть кода LinqToSql нашего уровня БД с фиктивной базой данных. Google "Irepository linq to sql unit test" для получения множества результатов. Я взял несколько идей из множества сообщений в блоге, которые будут возвращены при поиске, и создал систему, которая работает на удивление хорошо (но не без проблем).

0 голосов
/ 19 мая 2011

Если вы начнете транзакцию до запуска теста, а затем прервите транзакцию после запуска теста, у вас никогда не будет уже существующих строк данных.

Используйте [TestInitialize] и [TestCleanup] для до и послебежать;соответственно.

См. http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

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