Asp.net MVC 3 RTM Source Code 您可以从这里下载. 在源代码中有一个帮助处UnitTest中Exception的帮助类,我们还可以继续扩展。看下面的代码:
public static class ExceptionAssert { private const string ArgumentExceptionMessageFormat = "{0}\r\nParameter name: {1}"; public static void Throws<TException>(Action act) where TException : Exception { Throws<TException>(act, ex => true); } public static void Throws<TException, TResult>(Func<TResult> action) where TException : Exception { Throws<TException>(() => action(), ex => true); } public static void Throws<TException>(Action act, Func<TException,bool> condition) where TException : Exception { Exception ex = Capture.Exception(act); Assert.IsNotNull(ex, "The expected exception was not thrown"); Assert.IsInstanceOfType(ex, typeof(TException), "The exception thrown was not of the expected type"); Assert.IsTrue(condition((TException)ex), String.Format(@"Exception did not match the specified condition Actual Exception: {0}", ex)); } public static void Throws<TException>(Action action, string expectedMessage) where TException : Exception { Throws<TException>(action, ex => String.Equals(ex.Message, expectedMessage, StringComparison.Ordinal)); } public static void ThrowsArgNull(Action act, string paramName) { Throws<ArgumentNullException>(act, CreateArgNullChecker(paramName)); } public static void ThrowsArgNullOrEmpty(Action act, string paramName) { ThrowsArgumentException<ArgumentException>(act, paramName, CommonResources.Argument_Cannot_Be_Null_Or_Empty); } public static void ThrowsArgEmpty(Action act, string paramName) { ThrowsArgumentException<ArgumentException>(act, paramName, CommonResources.Argument_Must_Be_Null_Or_Non_Empty); } public static void ThrowsArgGreaterThan(Action act, string paramName, string value) { ThrowsArgumentException<ArgumentOutOfRangeException>(act, paramName, string.Format(CommonResources.Argument_Must_Be_GreaterThan, value)); } public static void ThrowsArgGreaterThanOrEqualTo(Action act, string paramName, string value) { ThrowsArgumentException<ArgumentOutOfRangeException>(act, paramName, string.Format(CommonResources.Argument_Must_Be_GreaterThanOrEqualTo, value)); } public static void ThrowsArgLessThan(Action act, string paramName, string value) { ThrowsArgumentException<ArgumentOutOfRangeException>(act, paramName, string.Format(CommonResources.Argument_Must_Be_LessThan, value)); } public static void ThrowsArgLessThanOrEqualTo(Action act, string paramName, string value) { ThrowsArgumentException<ArgumentOutOfRangeException>(act, paramName, string.Format(CommonResources.Argument_Must_Be_LessThanOrEqualTo, value)); } public static void ThrowsEnumArgOutOfRange<TEnumType>(Action act, string paramName) { ThrowsArgumentException<ArgumentOutOfRangeException>(act, paramName, String.Format(CommonResources.Argument_Must_Be_Enum_Member, typeof(TEnumType).Name)); } public static void ThrowsArgOutOfRange(Action act, string paramName, object minimum, object maximum, bool equalAllowed) { ThrowsArgumentException<ArgumentOutOfRangeException>(act, paramName, BuildOutOfRangeMessage(paramName, minimum, maximum, equalAllowed)); } internal static Func<ArgumentNullException, bool> CreateArgNullChecker(string paramName) { return ex => ex.ParamName.Equals(paramName); } private static string BuildOutOfRangeMessage(string paramName, object minimum, object maximum, bool equalAllowed) { if (minimum == null) { return String.Format(equalAllowed ? CommonResources.Argument_Must_Be_LessThanOrEqualTo : CommonResources.Argument_Must_Be_LessThan, maximum); } else if (maximum == null) { return String.Format(equalAllowed ? CommonResources.Argument_Must_Be_GreaterThanOrEqualTo : CommonResources.Argument_Must_Be_GreaterThan, minimum); } else { return String.Format(CommonResources.Argument_Must_Be_Between, minimum, maximum); } } public static void ThrowsArgumentException(Action act, string message) { ThrowsArgumentException<ArgumentException>(act, message); } public static void ThrowsArgumentException<TArgException>(Action act, string message) where TArgException : ArgumentException { Throws<TArgException>(act, ex => ex.Message.Equals(message)); } public static void ThrowsArgumentException(Action act, string paramName, string message) { ThrowsArgumentException<ArgumentException>(act, paramName, message); } public static void ThrowsArgumentException<TArgException>(Action act, string paramName, string message) where TArgException : ArgumentException { Throws<TArgException>(act, ex => ex.ParamName.Equals(paramName) && ex.Message.Equals(String.Format(ArgumentExceptionMessageFormat, message, paramName))); } }
public static class Capture { public static Exception Exception(Action act) { Exception ex = null; try { act(); } catch (Exception exc) { ex = exc; } return ex; } }
很有用,我们同样可以对它的UnitTest:
[TestClass] public class ExceptionAssertTest { [TestMethod] [ExpectedException(typeof(AssertFailedException))] public void DoesnotThrowException() { ExceptionAssert.Throws<ApplicationException>(() => { }, string.Empty); } [TestMethod] [ExpectedException(typeof(AssertFailedException))] public void ThrowException() { ExceptionAssert.Throws<ApplicationException>(() => { throw new ApplicationException(); }, string.Empty); } [TestMethod] [ExpectedException(typeof(AssertFailedException))] public void ThrowExceptionWithIncorrectMessage() { ExceptionAssert.Throws<ApplicationException>(() => { throw new ApplicationException("abc"); }, "cba"); } [TestMethod] public void ThrowExceptionWithCorrectMessage() { ExceptionAssert.Throws<ApplicationException>(() => { throw new ApplicationException("abcd"); }, "abcd"); } [TestMethod] [ExpectedException(typeof(AssertFailedException))] public void ThrowIncorrectException() { ExceptionAssert.Throws<ApplicationException>(() => { throw new SystemException(); }, string.Empty); } [TestMethod] [ExpectedException(typeof(AssertFailedException))] public void ThrowDerivedException() { ExceptionAssert.Throws<SystemException>(() => { throw new ArgumentException(); }, string.Empty); } [TestMethod] public void ExpectExceptionWithoutCheckingMessage() { ExceptionAssert.Throws<SystemException>(() => { throw new SystemException("abc"); }); } public static void SimpleMethod() { throw new Exception(); } public static int SimpleFunction() { throw new Exception(); } [TestMethod] public void UseExpressionInsteadOfLambda() { ExceptionAssert.Throws<Exception>(SimpleMethod); ExceptionAssert.Throws<Exception,int>(SimpleFunction); } }
在项目是它是这样用的,这样的代码是不是简洁的多:
[TestMethod] public void ValidationSummaryClassNameThrowsWhenAssignedNull() { // Act and Assert ExceptionAssert.ThrowsArgNull(() => HtmlHelper.ValidationSummaryClass = null, "value"); }
所以任意一个流行的开源项目,都有好的代码值得我们学习. 希望对您有所帮助。
还有一个简化版本 MsTest中实现类似NUnit中Assert.Throws
作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog。