[英]Correct work with exceptions
例如,我有以下方法:
public void MeetingNoteSave(int MeetingID, string note, bool IsInviter, string Username)
{
meeting = Get<Meeting>(p => p.MeetingID == MeetingID && p.UserInviter.aspnet_User.UserName == Username);
MeetingNoteSaveCheckings(meeting, MeetingID);
// some actions here
}
void MeetingNoteSaveCheckings(Meeting meeting, int MeetingID)
{
DateTime currentDateWithTime = DateTime.Now;
if (meeting == null)
{
throw new Exception("Meeting does not exist. MeetingID=" + MeetingID);
}
DateTime meetingTime = meeting.MeetingTime.Day.AddHours(meeting.MeetingTime.Hour).AddMinutes(meeting.MeetingTime.Minute);
if (meetingTime > currentDateWithTime)
{
throw new Exception("Meeting is future. MeetingID=" + MeetingID + ". Meeting time = '" + meetingTime + "', Current time='" + currentDateWithTime + "'");
}
}
因此,方法可能会引发2个异常-当根本不存在使用此类参数的会议或会议时间超过当前时间(应该是过去的时间或当前时间)时。
现在,我正在编写单元测试。 简单方法:
[TestMethod]
public void MeetingNoteSave()
{
_repository.MeetingNoteSave(1, "My note", true, "xxx@xxx.com");
}
当然,带有某些参数的呼叫单元测试将失败。 我想抓住这些情况,因此测试应该成功。 我可以通过两种方式来做。 首先很简单,但是有点脏:
try
{
_repository.MeetingNoteSave(1, "My note", true, "xxx@xxx.com");
}
catch(Exception ex)
{
if (ex.Message.IndexOf("Meeting does not exist")>=0)
{
// some actions
}
if (ex.Message.IndexOf("Meeting is future")>=0)
{
// some actions
}
}
因此,如果输入参数不正确,则测试将成功(因此,可以使用单元测试来测试参数不正确的方法),但由于遇到错误而失败。 好。
其他方法-创建特殊的虚拟异常,例如MeetingNullException和MeetingFutureException
public class MeetingNullException : Exception
{
}
public class MeetingFutureException : Exception
{
}
扔他们,抓住他们。 更正确,但是更多的代码。 虚拟代码。 哪种方法更正确?
两者都没有缺陷。 第二种方法是朝正确的方向发展:您应该避免抛出Exception
类型的一般Exception
; 特定的子类更具表现力。
然后,您需要在测试中使用[ExpectedException]
属性,该属性将使它们看起来像这样:
[TestMethod]
[ExpectedException(typeof(MeetingNullException))]
public void MeetingNoteSave_WithNotExistingMeeting()
{
_repository.MeetingNoteSave(1, "My note", true, "xxx@xxx.com");
}
[TestMethod]
[ExpectedException(typeof(MeetingFutureException ))]
public void MeetingNoteSave_WithFutureDate()
{
_repository.MeetingNoteSave(1, "My note", true, "xxx@xxx.com");
}
确保您对程序的每个可能流程都只有一个测试:2个异常表示2个测试。 我个人可能会避免创建特定的子类,而只使用ArgumentException
但这取决于您自己决定。 如果您具有表达性的测试名称,并且代码具有足够的自我说明性,那么您将知道无论如何都引用了哪个参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.