我通常不会使用,ExpectedException
除非我可以在单个语句中抛出异常 - 或者如果其他测试确保先前的语句不抛出异常.
在这里,您基本上有三个测试 - 您正在测试每个删除调用都会抛出异常.所有这一切ExpectedException
都是运行方法并检查它是否抛出了你要求的异常 - 它不会尝试从抛出异常的地方继续,期望它再次被抛出.
如果要检查特定代码段(而不仅仅是整个方法)抛出异常,请使用:
try { OperationThatShouldFail(); Assert.Fail("Expected exception"); } catch (DataAccessException) { // Expected (no need for an assertion though) }
(而且还没有ExpectedException
- 你不再期望测试方法会抛出.)
对于三个检查中的每一个,您都有这些块中的一个.或者(可能更好)只有三个测试,每个测试使用ExpectedException
但只有一行长.作为另一种选择,您可以将其try/catch
放入助手方法中.
您可能还希望在测试结束时断言相关表是空的 - 但这取决于您的情况.
编辑:至于你清理数据库时 - 我通常喜欢在每次测试开始时清理它,这样如果我只运行一次失败测试,我就可以看到数据库的状态.如果我要在拆解方法中清理它,我将丢失有价值的信息(或被迫留在调试器中).
编辑:另一种替代ExpectedException
(我怀疑现在在许多测试框架中)是一个像这样的通用方法:
static void ExpectException(Action action) where T : Exception { try { action(); Assert.Fail("Expected exception " + typeof(T)); } catch (T) { // Expected } }
然后,您可以使用lambda表达式在方法中轻松地(多次)调用它,假设您正在使用C#3.例如:
// Method name shortened for simplicity, and I'm assuming that type inference // will work too. public void NHibernateRepositoryBaseDelete() { ExpectException(() => DeleteHelper(myOrder, myOrder.OrderId)); ExpectException (() => DeleteHelper(myOrderDetail, myOrderDetail.OrderDetailId)); ExpectException (() => DeleteHelper(mySchedule, mySchedule.ScheduleId)); }
将您的单元测试代码包装在try/finally块中,并在finally部分中清理您的数据库.
[TestMethod] [ExpectedException(typeof(DataAccessException))] public void NHibernateRepositoryBaseDelete() { try { NHibernateRepositoryBaseDeleteHelper(myOrder, myOrder.OrderId); NHibernateRepositoryBaseDeleteHelper (myOrderDetail, myOrderDetail.OrderDetailId); NHibernateRepositoryBaseDeleteHelper (mySchedule, mySchedule.ScheduleId); } finally { // clean up database here } }