Jus*_*ook 5 c# unit-testing exception
我正在测试抽象基础存储库类的delete方法,该类由其他几个存储库类继承.MyTestRepository继承了base,因此我可以对base的方法运行测试,而不会限制我的测试使用具体的类.当我运行我的单元测试时它会通过,但我注意到之后我在测试数据库中有几个OrderDetail和Schedule对象,这些对象是由测试生成的(对象是在测试初始化期间创建的)并且没有删除,而Order对象被删除.我添加了一些断点,并注意到一旦helper方法结束并且抛出了预期的异常,测试就会结束,而其他对helper的调用永远不会发生.
这是我第一次尝试进行单元测试.我的方法是错的吗?ExpectedException是否按预期工作,我是在滥用它,还是我应该使用另一种工具?我能想到的唯一方法就是在helper中设置try catch块,并在捕获DataAccessException时断言为true.
[TestMethod]
[ExpectedException(typeof(DataAccessException))]
public void NHibernateRepositoryBaseDelete()
{
NHibernateRepositoryBaseDeleteHelper<Order, int>(myOrder, myOrder.OrderId);
NHibernateRepositoryBaseDeleteHelper<OrderDetail, int>(myOrderDetail, myOrderDetail.OrderDetailId);
NHibernateRepositoryBaseDeleteHelper<Schedule, int>(mySchedule, mySchedule.ScheduleId);
}
private static void NHibernateRepositoryBaseDeleteHelper<T, TKey>(T myItem, TKey myItemId)
{
MyTestRepository<T, TKey> myRepository = new MyTestRepository<T, TKey>();
myRepository.Delete(myItem);
myRepository.CommitChanges();
myRepository.GetById(myItemId, false);
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 11
我通常不会使用,ExpectedException除非我可以在单个语句中抛出异常 - 或者如果其他测试确保先前的语句不抛出异常.
在这里,您基本上有三个测试 - 您正在测试每个删除调用都会抛出异常.所有这一切ExpectedException都是运行方法并检查它是否抛出了你要求的异常 - 它不会尝试从抛出异常的地方继续,期望它再次被抛出.
如果要检查特定代码段(而不仅仅是整个方法)抛出异常,请使用:
try
{
OperationThatShouldFail();
Assert.Fail("Expected exception");
}
catch (DataAccessException)
{
// Expected (no need for an assertion though)
}
Run Code Online (Sandbox Code Playgroud)
(而且还没有ExpectedException- 你不再期望测试方法会抛出.)
对于三个检查中的每一个,您都有这些块中的一个.或者(可能更好)只有三个测试,每个测试使用ExpectedException但只有一行长.作为另一种选择,您可以将其try/catch放入助手方法中.
您可能还希望在测试结束时断言相关表是空的 - 但这取决于您的情况.
编辑:至于你清理数据库时 - 我通常喜欢在每次测试开始时清理它,这样如果我只运行一次失败测试,我就可以看到数据库的状态.如果我要在拆解方法中清理它,我将丢失有价值的信息(或被迫留在调试器中).
编辑:另一种替代ExpectedException(我怀疑现在在许多测试框架中)是一个像这样的通用方法:
static void ExpectException<T>(Action action)
where T : Exception
{
try
{
action();
Assert.Fail("Expected exception " + typeof(T));
}
catch (T)
{
// Expected
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用lambda表达式在方法中轻松地(多次)调用它,假设您正在使用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));
}
Run Code Online (Sandbox Code Playgroud)
小智 5
将您的单元测试代码包装在try/finally块中,并在finally部分中清理您的数据库.
[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
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1845 次 |
| 最近记录: |