Решение состоит в том, чтобы искать элемент с GetElementsByTagName
каждый раз вместо повторного использования ссылки.
Я обычно не использую ExpectedException
если я не могу заставить исключение быть брошенным в отдельного оператора - или если другие тесты гарантируют, чтобы более ранние операторы не выдавали исключение.
Здесь, Вы в основном получили три теста - Вы тестируете это, каждый из тех удаляет вызовы, выдаст исключение. Все это ExpectedException
делает выполняется метод, и проверьте, что он выдал исключение, к которому Вы спросили это - он не пытается продолжиться от того, где исключение было выдано, ожидая, что это будет брошено снова.
Если Вы хотите проверить, что исключение выдается определенной частью кода (а не просто целый метод) использование:
try
{
OperationThatShouldFail();
Assert.Fail("Expected exception");
}
catch (DataAccessException)
{
// Expected (no need for an assertion though)
}
(И не иметь ExpectedException
больше - Вы больше не ожидаете метода тестирования бросить.)
У Вас был бы один из этих блоков для каждой из трех проверок. Кроме того (и вероятно лучше) просто имеют три теста, каждый из которых использует ExpectedException
но только одна строка долго. Как другая альтернатива, Вы могли поместить try/catch
в Ваш вспомогательный метод.
Вы могли бы также хотеть иметь утверждение в конце теста, что соответствующие таблицы пусты - но это зависит от Вашей ситуации.
Править: Что касается того, когда Вы очищаете базу данных - мне обычно нравится чистить ее в начале каждого теста так, чтобы, если я работаю просто, единственный провальный тест I видел состояние базы данных впоследствии. Если бы я должен был очистить его в методе разрушения, я потерял бы ценную информацию (или быть вынужденным остаться в отладчике).
Править: Другая альтернатива ExpectedException
(который я подозреваю, находится во многих средах тестирования теперь), должен иметь общий метод как это:
static void ExpectException<T>(Action action)
where T : Exception
{
try
{
action();
Assert.Fail("Expected exception " + typeof(T));
}
catch (T)
{
// Expected
}
}
Можно затем назвать его легко (многократно) из метода с помощью лямбда-выражения для действия, предположив использование C# 3. Например:
// Method name shortened for simplicity, and I'm assuming that type inference
// will work too.
public void NHibernateRepositoryBaseDelete()
{
ExpectException<DataAccessException>(() =>
DeleteHelper(myOrder, myOrder.OrderId));
ExpectException<DataAccessException>(() =>
DeleteHelper(myOrderDetail, myOrderDetail.OrderDetailId));
ExpectException<DataAccessException>(() =>
DeleteHelper(mySchedule, mySchedule.ScheduleId));
}
Перенесите свой код модульного теста в блок попытки/наконец и очистите свою базу данных в наконец часть.
[TestMethod]
[ExpectedException(typeof(DataAccessException))]
public void NHibernateRepositoryBaseDelete()
{
try
{
NHibernateRepositoryBaseDeleteHelper<Order, int>(myOrder, myOrder.OrderId);
NHibernateRepositoryBaseDeleteHelper<OrderDetail, int>(myOrderDetail, myOrderDetail.OrderDetailId);
NHibernateRepositoryBaseDeleteHelper<Schedule, int>(mySchedule, mySchedule.ScheduleId);
}
finally
{
// clean up database here
}
}