Rhino Mocks - использование AssertWasCalled на Common.Logging ILog.Debug
У меня возникают проблемы с использованием Rhino Mocks, чтобы утверждать, что метод был вызван (и в идеале с определенным параметром). Метод называется ILog.Debug(FormatMessageHandler) в Common.Logging 2.0 с использованием нового синтаксиса lamba. Он отлично работает, используя старый способ ILog.Debug (строка).
// Sample Code to Test
public int TestFuncLambda(ILog log, int a, int b)
{
log.Debug(m => m("TestFunc START"));
int c = a + b;
log.Debug(m => m("TestFunc END"));
return c;
}
public int TestFunc(ILog log, int a, int b)
{
log.Debug("TestFunc START");
int c = a + b;
log.Debug("TestFunc END");
return c;
}
[TestMethod]
public void Should_log_start_TestFuncLamba()
{
var logger = MockRepository.GenerateMock<ILog>();
logger.Stub(x => x.IsDebugEnabled).Return(true);
TestFuncLambda(logger, 1, 2);
// Doesn't work, says zero calls plus I'm not sure how to check for the word "START" in the string either
logger.AssertWasCalled(x => x.Debug(Arg<FormatMessageHandler>.Is.Anything), o => o.IgnoreArguments());
}
[TestMethod]
public void Should_log_start_TestFunc()
{
var logger = MockRepository.GenerateMock<ILog>();
logger.Stub(x => x.IsDebugEnabled).Return(true);
TestFunc(logger, 1, 2);
// Works fine
logger.AssertWasCalled(x => x.Debug(Arg<string>.Matches(Text.Contains("START"))));
}
3 ответа
Я понял. Я скучал по части действия для делегата. Правильный синтаксис:
logger.AssertWasCalled(x => x.Debug(Arg<Action<FormatMessageHandler>>.Is.Anything));
скорее, чем
logger.AssertWasCalled(x => x.Debug(Arg<FormatMessageHandler>.Is.Anything), o => o.IgnoreArguments());
Как уже упоминалось, o.IgnoreArguments() был избыточным и не обязательным.
Здесь я собираюсь предположить, что вы просто возитесь с Rhinomocks, и это не имеет ничего общего с каркасом логирования, верно? Я говорю это потому, что в ваших тестах нет конкретных реализаций, только ложные.
Без тестирования вашего кода эта строка выглядит так, что она всегда будет нулевой:
logger.AssertWasCalled(x => x.Debug(Arg<FormatMessageHandler>.Is.Anything), o => o.IgnoreArguments());
потому что ваш фактический метод TestFunc() передает строки в log.Debug, а не FormatMessageHandler:
Поэтому имеет смысл, что количество звонков равно нулю. Добавьте строку в TestFunc() следующим образом:
log.Debug(new FormatMessageHandler());
и посмотрим, исправит ли это.
Сначала создайте конкретный класс, чтобы увидеть, вызывается ли правильный метод Debug() в TestFuncLambda. Это гарантирует, что он не выполняет какое-то странное преобразование лямбды в строку.
После того, как вы убедились, что он должен вызывать правильную версию, вы изолировали проблему с RhinoMocks. Это может быть ошибка с насмешками носорога. Итак, давайте уменьшим набор ошибок, но поместим лямбду в новый FormatMessageHandler(), прежде чем передать его в Debug. Это гарантирует, что правильная макетируемая функция вызывается, а не переводится как-то еще.
Если вы не нашли ошибку на этом этапе, и она все еще не работает, попробуйте создать экземпляр FormatMessageHandler() и сохранить его как статическую переменную-член (просто чтобы проверить, что не так). Передайте сохраненное в вызове TestFuncDebug функции Debug() и AssertWasCalled(). Если это не сработает, у меня нет идей.
Кстати, я не знаю, что такое IgnoreArguments(), но мне никогда не нужно вызывать его в моих вызовах RhinoMocks для AssertWasCalled. Обычно с Arg<>.Is.Anthing работает отлично.