Normally we use Debug.Assert() for code contracts. To stop the Debug.Assert() statements from activating during unit tests, add the following to te unit tests application config file ("App.Config"):
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <assert assertuienabled="false"/> <!-- Disable Debug.Assert() when running unit tests in debug mode. --> </system.diagnostics> </configuration>Following is a code contract type class that can make code assertions without throwing an Assert dialog during an NUnit test. Also the code contracts will be logged in release. A potential product failure in the field could be traced back to a code contract failure.
using System; using System.Diagnostics; using System.Runtime.CompilerServices; namespace Common.CodeContracts { /// <summary> /// A simple code contract class to replace Debug.Assert(). It can be used in release /// and will log code contract failures to the Trace output window. /// </summary> public static class RuntimeCodeContract { // Switch on the Debugger.Break when required public static bool DebuggerBreakOnFailure { get; set; } = false; public static void Requires(bool condition, string message, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0) { if (!condition) { var msg = $"Code contract failure detected: \"{message}\" in member \"{member}\" on line {line} in file \"{file}\""; Trace.TraceError(msg); if (DebuggerBreakOnFailure) { Debugger.Break(); // Use the call stack window to find the invoker location } //throw new InvalidOperationException(msg); } } public static void RequiresArgument(bool condition, string paramName, string message = "", [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0) { if (!condition) { var msg = $"Argument requirement failure detected: {message} \"{paramName}\" in member \"{member}\" on line {line} in file \"{file}\""; Trace.TraceError(msg); if (DebuggerBreakOnFailure) { Debugger.Break(); // Use the call stack window to find the invoker location } //throw new ArgumentException(message, paramName); } } public static void RequiresArgumentNotNull(object parameter, string paramName, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0) { if (parameter == null) { var msg = $"Argument {paramName} was null in member {member} on line {line} in file {file}"; Trace.TraceError(msg); if (DebuggerBreakOnFailure) { Debugger.Break(); // Use the call stack window to find the invoker location } //throw new ArgumentNullException(msg, paramName); } } } }It is also a good example of using the compiler attributes "CallerFilePath", "CallerMemberName", and "CallerLineNumber" for diagnostics.
No comments:
Post a Comment