Я согласен с Krzysztof, если вы хотите добавить ведение журнала через AOP, ответственность и детали реализации ведения журнала должны быть прозрачны для вызывающей стороны.Таким образом, это то, что перехватчик может владеть.Я попытаюсь обрисовать, как я это проверил бы.
Если я правильно следую за вопросом, ваш ILoggable на самом деле является просто контейнером именования для аннотирования класса, чтобы перехватчик мог определить, должен ли он выполнять регистрацию.Он предоставляет свойство, которое содержит Logger.(Недостатком этого является то, что класс все еще должен настраивать Logger.)
public interface ILoggable
{
ILogger { get; set; }
}
Тестирование перехватчика должно быть простым процессом.Единственная проблема, которую я вижу, которую вы представили, состоит в том, как вручную создать входной параметр IInvocation , чтобы он напоминал данные времени выполнения.Вместо того, чтобы пытаться воспроизвести это с помощью насмешек и т. Д., Я бы посоветовал вам протестировать его с помощью классической проверки на основе состояния: создайте прокси-сервер, который использует ваш перехватчик, и убедитесь, что ваш журнал отражает то, что вы ожидаете.
Это может показатьсяЭто немного больше работы, но это хороший пример того, как перехватчик работает независимо от других частей вашей кодовой базы.Другие разработчики в вашей команде извлекают выгоду из этого, поскольку они могут ссылаться на этот пример в качестве учебного пособия.
public class TypeThatSupportsLogging : ILoggable
{
public ILogger { get; set; }
public virtual void MethodToIntercept()
{
}
public void MethodWithoutLogging()
{
}
}
public class TestLogger : ILogger
{
private StringBuilder _output;
public TestLogger()
{
_output = new StringBuilder();
}
public void DebugFormat(string message, params object[] args)
{
_output.AppendFormat(message, args);
}
public string Output
{
get { return _output.ToString(); }
}
}
[TestFixture]
public class LoggingWithDebugInterceptorTests
{
protected TypeThatSupportsLogging Input;
protected LoggingWithDebugInterceptor Subject;
protected ILogger Log;
[Setup]
public void Setup()
{
// create your interceptor
Subject = new LoggingWithDebugInterceptor();
// create your proxy
var generator = new Castle.DynamicProxy.ProxyGenerator();
Input = generator.CreateClassProxy<TypeThatSupportLogging>( Subject );
// setup the logger
Log = new TestLogger();
Input.Logger = Log;
}
[Test]
public void DemonstrateThatTheInterceptorLogsInformationAboutVirtualMethods()
{
// act
Input.MethodToIntercept();
// assert
StringAssert.Contains("MethodToIntercept", Log.Output);
}
[Test]
public void DemonstrateNonVirtualMethodsAreNotLogged()
{
// act
Input.MethodWithoutLogging();
// assert
Assert.AreEqual(String.Empty, Log.Output);
}
}