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 работает отлично.

Другие вопросы по тегам