繁体   English   中英

例外情况下正确工作

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM