@@ -302,9 +302,9 @@ private static Task<string> AcquireTokenAsync(string authorityURL, string userID
302302 SecureString securePassword = new SecureString ( ) ;
303303
304304 securePassword . MakeReadOnly ( ) ;
305- #pragma warning disable CS0618 // Type or member is obsolete
305+ #pragma warning disable CS0618 // Type or member is obsolete
306306 result = app . AcquireTokenByUsernamePassword ( scopes , userID , password ) . ExecuteAsync ( ) . Result ;
307- #pragma warning restore CS0618 // Type or member is obsolete
307+ #pragma warning restore CS0618 // Type or member is obsolete
308308
309309 return result . AccessToken ;
310310 } ) ;
@@ -389,7 +389,7 @@ public static string GetSqlServerProperty(SqlConnection connection, ServerProper
389389 }
390390 }
391391
392- #nullable disable
392+ #nullable restore
393393
394394 private static bool GetSQLServerStatusOnTDS8 ( string connectionString )
395395 {
@@ -951,62 +951,89 @@ public static void AssertEqualsWithDescription(object expectedValue, object actu
951951 }
952952 }
953953
954- public static TException AssertThrowsWrapper < TException > ( Action actionThatFails , string exceptionMessage = null , bool innerExceptionMustBeNull = false , Func < TException , bool > customExceptionVerifier = null ) where TException : Exception
954+ #nullable enable
955+
956+ /// <summary>
957+ /// Asserts that <paramref name="actionThatFails"/> throws an exception of type
958+ /// <typeparamref name="TException"/> and optionally verifies that its message contains
959+ /// <paramref name="exceptionMessage"/>.
960+ /// </summary>
961+ public static TException AssertThrows < TException > (
962+ Action actionThatFails ,
963+ string ? exceptionMessage = null )
964+ where TException : Exception
955965 {
956966 TException ex = Assert . Throws < TException > ( actionThatFails ) ;
967+
957968 if ( exceptionMessage != null )
958969 {
959970 Assert . True ( ex . Message . Contains ( exceptionMessage ) ,
960971 string . Format ( "FAILED: Exception did not contain expected message.\n Expected: {0}\n Actual: {1}" , exceptionMessage , ex . Message ) ) ;
961972 }
962973
963- if ( innerExceptionMustBeNull )
964- {
965- Assert . True ( ex . InnerException == null , "FAILED: Expected InnerException to be null." ) ;
966- }
967-
968- if ( customExceptionVerifier != null )
969- {
970- Assert . True ( customExceptionVerifier ( ex ) , "FAILED: Custom exception verifier returned false for this exception." ) ;
971- }
972-
973974 return ex ;
974975 }
975976
976- public static TException AssertThrowsWrapper < TException , TInnerException > ( Action actionThatFails , string exceptionMessage = null , string innerExceptionMessage = null , bool innerExceptionMustBeNull = false , Func < TException , bool > customExceptionVerifier = null ) where TException : Exception
977+ /// <summary>
978+ /// Asserts that <paramref name="actionThatFails"/> throws <typeparamref name="TException"/>
979+ /// whose <see cref="Exception.InnerException"/> is of type <typeparamref name="TInnerException"/>.
980+ /// Optionally verifies message text on both the outer and inner exceptions.
981+ /// </summary>
982+ public static TException AssertThrowsInner < TException , TInnerException > (
983+ Action actionThatFails ,
984+ string ? exceptionMessage = null ,
985+ string ? innerExceptionMessage = null )
986+ where TException : Exception
987+ where TInnerException : Exception
977988 {
978- TException ex = AssertThrowsWrapper < TException > ( actionThatFails , exceptionMessage , innerExceptionMustBeNull , customExceptionVerifier ) ;
989+ TException ex = AssertThrows < TException > ( actionThatFails , exceptionMessage ) ;
990+
991+ Assert . NotNull ( ex . InnerException ) ;
992+ Assert . IsAssignableFrom < TInnerException > ( ex . InnerException ) ;
979993
980994 if ( innerExceptionMessage != null )
981995 {
982- Assert . True ( ex . InnerException != null , "FAILED: Cannot check innerExceptionMessage because InnerException is null." ) ;
983996 Assert . True ( ex . InnerException . Message . Contains ( innerExceptionMessage ) ,
984997 string . Format ( "FAILED: Inner Exception did not contain expected message.\n Expected: {0}\n Actual: {1}" , innerExceptionMessage , ex . InnerException . Message ) ) ;
985998 }
986999
9871000 return ex ;
9881001 }
9891002
990- public static TException AssertThrowsWrapper < TException , TInnerException , TInnerInnerException > ( Action actionThatFails , string exceptionMessage = null , string innerExceptionMessage = null , string innerInnerExceptionMessage = null , bool innerInnerInnerExceptionMustBeNull = false ) where TException : Exception where TInnerException : Exception where TInnerInnerException : Exception
1003+ /// <summary>
1004+ /// Asserts that <paramref name="actionThatFails"/> throws <typeparamref name="TException"/>
1005+ /// whose <see cref="Exception.InnerException"/> is either <typeparamref name="TInnerException"/>
1006+ /// or <typeparamref name="TAlternateInnerException"/>. Use this when a race condition
1007+ /// (e.g. disposal during an async read) may cause the inner exception type to vary
1008+ /// between runs. The <paramref name="innerExceptionMessage"/> is only verified when the
1009+ /// inner exception is <typeparamref name="TInnerException"/>.
1010+ /// </summary>
1011+ public static TException AssertThrowsInnerWithAlternate < TException , TInnerException , TAlternateInnerException > (
1012+ Action actionThatFails ,
1013+ string ? exceptionMessage = null ,
1014+ string ? innerExceptionMessage = null )
1015+ where TException : Exception
1016+ where TInnerException : Exception
1017+ where TAlternateInnerException : Exception
9911018 {
992- TException ex = AssertThrowsWrapper < TException , TInnerException > ( actionThatFails , exceptionMessage , innerExceptionMessage ) ;
993- if ( innerInnerInnerExceptionMustBeNull )
994- {
995- Assert . True ( ex . InnerException != null , "FAILED: Cannot check innerInnerInnerExceptionMustBeNull since InnerException is null" ) ;
996- Assert . True ( ex . InnerException . InnerException == null , "FAILED: Expected InnerInnerException to be null." ) ;
997- }
1019+ TException ex = AssertThrows < TException > ( actionThatFails , exceptionMessage ) ;
9981020
999- if ( innerInnerExceptionMessage != null )
1021+ Assert . NotNull ( ex . InnerException ) ;
1022+ Assert . True (
1023+ ex . InnerException is TInnerException or TAlternateInnerException ,
1024+ $ "Expected { typeof ( TInnerException ) . Name } or { typeof ( TAlternateInnerException ) . Name } , got: { ex . InnerException ? . GetType ( ) } ") ;
1025+
1026+ if ( innerExceptionMessage != null && ex . InnerException is TInnerException )
10001027 {
1001- Assert . True ( ex . InnerException != null , "FAILED: Cannot check innerInnerExceptionMessage since InnerException is null" ) ;
1002- Assert . True ( ex . InnerException . InnerException != null , "FAILED: Cannot check innerInnerExceptionMessage since InnerInnerException is null" ) ;
1003- Assert . True ( ex . InnerException . InnerException . Message . Contains ( innerInnerExceptionMessage ) ,
1004- string . Format ( "FAILED: Inner Exception did not contain expected message.\n Expected: {0}\n Actual: {1}" , innerInnerExceptionMessage , ex . InnerException . InnerException . Message ) ) ;
1028+ Assert . True ( ex . InnerException . Message . Contains ( innerExceptionMessage ) ,
1029+ string . Format ( "FAILED: Inner Exception did not contain expected message.\n Expected: {0}\n Actual: {1}" , innerExceptionMessage , ex . InnerException . Message ) ) ;
10051030 }
10061031
10071032 return ex ;
10081033 }
10091034
1035+ #nullable restore
1036+
10101037 public static TException ExpectFailure < TException > ( Action actionThatFails , string [ ] exceptionMessages , bool innerExceptionMustBeNull = false , Func < TException , bool > customExceptionVerifier = null ) where TException : Exception
10111038 {
10121039 try
@@ -1320,7 +1347,7 @@ public static string GetMachineFQDN(string hostname)
13201347 }
13211348 return fqdn . ToString ( ) ;
13221349 }
1323- }
13241350
1325- #nullable disable
1351+ #nullable restore
1352+ }
13261353}
0 commit comments