Dimenticavo… once again :-)
Eccoci:
Utilizzando questa come dto possiamo scrivere qualcosa del tipo:class SourceInfo { public readonly static SourceInfo Empty = new SourceInfo( "", "", MemberTypes.Custom ); public SourceInfo( String methodName, String className, MemberTypes sourceType ) { this.MethodName = methodName; this.ClassName = className; this.SourceType = sourceType; } public String MethodName { get; private set; } public String ClassName { get; private set; } public MemberTypes SourceType { get; private set; } }
Che altro non fa che recuperare le informazioni sullo stack frame precedente al nostro che è necessariamente il chiamante.public static class Ensure { public static EnsureThat ( T obj ) { SourceInfo si = SourceInfo.Empty; var st = new StackTrace( 1 ); if( st.FrameCount > 0 ) { var f = st.GetFrame( 0 ); var mi = f.GetMethod(); if( mi != null ) { si = new SourceInfo( mi.DeclaringType.Name, mi.Name, mi.MemberType ); } } return new Ensure ( obj, si ); } }
A questo punto diventa abbastanza banale far passare un test come questo:
.m[TestMethod] public void ensure_getFullErrorMessage_should_contain_all_relevant_information() { var obj = Ensure.That( "" ); String actual = obj.GetFullErrorMessage( "validator specific message" ); var containsClassName = actual.Contains( typeof( ValidatorTest ).Name ); var containsMethodName = actual.Contains( typeof( ValidatorTest ).Name ); containsClassName.ShouldBeTrue(); containsMethodName.ShouldBeTrue(); }