diff --git a/src/Chapter18.Tests/Listing18..07a..GenericAttributes.cs b/src/Chapter18.Tests/Listing18.25a..GenericAttributes.Tests.cs similarity index 70% rename from src/Chapter18.Tests/Listing18..07a..GenericAttributes.cs rename to src/Chapter18.Tests/Listing18.25a..GenericAttributes.Tests.cs index 15a1811fa..a702ff245 100644 --- a/src/Chapter18.Tests/Listing18..07a..GenericAttributes.cs +++ b/src/Chapter18.Tests/Listing18.25a..GenericAttributes.Tests.cs @@ -1,14 +1,15 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter18.Listing18_07a.Tests; +namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter18.Listing18_25a.Tests; +#if NET7_0_OR_GREATER [TestClass] public class GenericExceptionTests { [TestMethod] public void ExpectedExceptionIsThrown() { - ExpectedException.AssertExceptionThrown( + ExpectedException.AssertExceptionThrown( SampleTests.ThrowArgumentNullExceptionTest); } @@ -16,7 +17,8 @@ public void ExpectedExceptionIsThrown() [ExpectedException(typeof(InvalidOperationException))] public void ExpectedExceptionIsNotThrown() { - ExpectedException.AssertExceptionThrown( + ExpectedException.AssertExceptionThrown( () => { }); } -} \ No newline at end of file +} +#endif // NET7_0_OR_GREATER \ No newline at end of file diff --git a/src/Chapter18.Tests/Listing18.25b..CallerArgumentExpression.Tests.cs b/src/Chapter18.Tests/Listing18.25b..CallerArgumentExpression.Tests.cs new file mode 100644 index 000000000..718792d8b --- /dev/null +++ b/src/Chapter18.Tests/Listing18.25b..CallerArgumentExpression.Tests.cs @@ -0,0 +1,61 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter18.Listing18_25b.Tests; + +#if NET7_0_OR_GREATER +[TestClass] +public class GenericExceptionTests +{ + [TestMethod] + public void ExpectedExceptionIsThrown() + { + ExpectedException.AssertExceptionThrown( + SampleTests.ThrowArgumentNullExceptionTest); + } + + [TestMethod] + public void VerifyExpectedExceptionMessage() + { + try + { + ExpectedException.AssertExceptionThrown( + () => { }); + } + catch(InvalidOperationException exception) + { + Assert.IsTrue(exception.Message.Contains("'() => { }'")); + } + } + + [TestMethod] + public void Method() + { + try + { + SampleTests.Method(); + } + catch (InvalidOperationException exception) + { + Assert.IsTrue( + exception.Message.Contains("'() => { }'") && + exception.Message.Contains("'Method'") && + exception.Message.Contains("'./FileName.cs'")); + // The expected exception, System.DivideByZeroException, + // was not thrown by the expression, 'Method' in the method, './FileName.cs', and file 'C:\Git\EssentialCSharp\src\Chapter18\Listing18.25b.CallerArgumentExpression.cs'. + } + } + + private object PassingMethodNameAndFileName() + { + throw new NotImplementedException(); + } + + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void ExpectedExceptionIsNotThrown() + { + ExpectedException.AssertExceptionThrown( + () => { }); + } +} +#endif // NET7_0_OR_GREATER \ No newline at end of file diff --git a/src/Chapter18/Listing18 .07a.GenericException.cs b/src/Chapter18/Listing18 .07a.GenericException.cs deleted file mode 100644 index e60f0bc05..000000000 --- a/src/Chapter18/Listing18 .07a.GenericException.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter18.Listing18_07a; - -#region INCLUDE -public class SampleTests -{ - [ExpectedException] - public static void ThrowArgumentNullExceptionTest() - { - var result = 1/"".Length; - } -} -#endregion INCLUDE - -[AttributeUsage(AttributeTargets.Method)] -public class ExpectedException : Attribute where TException : Exception -{ - public static void AssertExceptionThrown(Action testMethod) - { - try - { - testMethod(); - throw new InvalidOperationException( - $"The expected exception, {typeof(TException).FullName} was not thrown."); - } - catch (TException) - { - - } - } -} diff --git a/src/Chapter18/Listing18.25a.GenericException.cs b/src/Chapter18/Listing18.25a.GenericException.cs new file mode 100644 index 000000000..55679154d --- /dev/null +++ b/src/Chapter18/Listing18.25a.GenericException.cs @@ -0,0 +1,41 @@ +namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter18.Listing18_25a; + +#if NET7_0_OR_GREATER +#region INCLUDE +public class SampleTests +{ + #region HIGHLIGHT + [ExpectedException] + #endregion HIGHLIGHT + public static void ThrowArgumentNullExceptionTest() + { + var result = 1/"".Length; + } +} + +[AttributeUsage(AttributeTargets.Method)] +#region HIGHLIGHT +public class ExpectedException : + Attribute where TException : Exception +#endregion HIGHLIGHT +{ + public static TException AssertExceptionThrown(Action testMethod) + { + try + { + testMethod(); + throw new InvalidOperationException( + $"The expected exception, { + typeof(TException).FullName }, was not thrown."); + } + catch (TException exception) + { + return exception; + } + } + + // Attribute detection + // ... +} +#endregion INCLUDE +#endif // NET7_0_OR_GREATER \ No newline at end of file diff --git a/src/Chapter18/Listing18.25b.CallerArgumentExpression.cs b/src/Chapter18/Listing18.25b.CallerArgumentExpression.cs new file mode 100644 index 000000000..6c18de875 --- /dev/null +++ b/src/Chapter18/Listing18.25b.CallerArgumentExpression.cs @@ -0,0 +1,59 @@ +using System.Runtime.CompilerServices; + +namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter18.Listing18_25b; + +#if NET7_0_OR_GREATER +#region INCLUDE +public class SampleTests +{ + #region HIGHLIGHT + [ExpectedException] + #endregion HIGHLIGHT + public static void ThrowArgumentNullExceptionTest() + { + var result = 1/"".Length; + } + +public static void Method() +{ + ExpectedException.AssertExceptionThrown( + () => throw new Exception()); +} +} + +[AttributeUsage(AttributeTargets.Method)] +public class ExpectedException : + Attribute where TException : Exception +{ +#region HIGHLIGHT +public static TException AssertExceptionThrown( + Action testAction, + [CallerArgumentExpression(nameof(testAction))] + string testExpression = null!, + [CallerMemberName]string testActionMemberName = null!, + [CallerFilePath]string testActionFileName = null! + ) +#endregion HIGHLIGHT +{ + try + { + testAction(); + throw new InvalidOperationException( + $"The expected exception, { + typeof(TException).FullName }, was not thrown" + + $" by the expression '{ + testExpression }' in the method '{ + testActionMemberName }' and file '{ + testActionFileName }'."); + } + catch (TException exception) + { + return exception; + } +} + + // Attribute detection + // ... +} +#endregion INCLUDE +#endif // NET7_0_OR_GREATER \ No newline at end of file diff --git a/src/Chapter18/Listing18.26.DynamicProgrammingUsingReflection.cs b/src/Chapter18/Listing18.26.DynamicProgrammingUsingReflection.cs index 1d52070c9..c7f9c5248 100644 --- a/src/Chapter18/Listing18.26.DynamicProgrammingUsingReflection.cs +++ b/src/Chapter18/Listing18.26.DynamicProgrammingUsingReflection.cs @@ -5,6 +5,7 @@ public class Program public static void Main() { #region INCLUDE + // ... dynamic data = "Hello! My name is Inigo Montoya"; Console.WriteLine(data);