Unit Test & Log4net

У меня есть unit test тестирование действия в моем контроллере, действие записывается в log4net.

Когда я запускаю свое действие, он хорошо работает - записывается в log4net.

Однако, когда я запускаю unit test - действие не записывается в log4net, но не вызывает никаких исключений.

У кого-нибудь есть решение?

Ответ 1

// ARRANGE
var memoryAppender = new MemoryAppender();
BasicConfigurator.Configure(memoryAppender);

// ACT
_sut.DoWhatever();

// ASSERT - using xunit - change the expression to fit your purposes
Assert.True(memoryAppender.GetEvents().Any(le => le.Level == Level.Warn), "Expected warning messages in the logs");

Вам не требуется , чтобы добавить в другой слой косвенности с помощью интерфейса ведения журнала (если вы этого не хотите). Я использовал абстрактный путь в течение многих лет, но теперь я перехожу к простому использованию MemoryAppender, поскольку он тестирует то, что на самом деле происходит. Просто убедитесь, что. После того, как вы подтвердите(), добавьте приложение.

Ответ 2

Log4net не генерирует исключений: http://logging.apache.org/log4net/release/faq.html

Запись в журнал на диске или в базе данных в unit test является контрпродуктивной; все дело в автоматизации. Вам не нужно проверять журналы каждый раз, когда вы запускаете тесты.

Если вам действительно нужно проверить, что был сделан вызов для регистрации чего-либо, вы должны издеваться над интерфейсом ILog и утверждать, что был вызван соответствующий метод.

Если вы используете насмешливую структуру, это тривиально. Если это не так, вы можете создать класс TestLogger, который реализует или частично реализует ILog и предоставляет дополнительные свойства, которые показывают, сколько раз вызывался данный метод. Ваши утверждения будут проверять, что методы были вызваны как ожидалось.

Вот пример тестируемого класса:

  public class MyComponent
  {
    private readonly ILog _log;

    public MyComponent(ILog log)
    {
      _log = log;
    }

    public string DoSomething(int arg)
    {
      _log.InfoFormat("Argument was [{0}]", arg);
      return arg.ToString();
    }
  }

и тест (используя Rhino.Mocks, чтобы издеваться над ILog):

[TestClass]
  public class MyComponentTests
  {
    [TestMethod]
    public void DoSomethingTest()
    {
      var logger = MockRepository.GenerateStub<ILog>();
      var component = new MyComponent(logger);

      var result = component.DoSomething(8);

      Assert.AreEqual("8", result);
      logger.AssertWasCalled(l => l.InfoFormat(Arg<string>.Is.Anything, Arg<int>.Is.Equal(8)));
    }
  }

Ответ 3

Попробуйте добавить:

[assembly: log4net.Config.XmlConfigurator()]

К AssemblyInfo.cs (или init log4net любым другим способом). Нашел этот ответ здесь

Ответ 4

Это ваша конфигурация log4net. Прямо сейчас это может быть в вашем файле web.config или log4net.config в сети /bin. Вы должны разместить его в общем месте и сделать его доступным как для веб-приложения, так и для тестирования. Или вы должны поместить его в свой файл unittest.project = > app.config. Но если у вас много проектов испытаний, это будет дублироваться по количеству мест. Поэтому идеальным было бы поставить его в обычное место.

Ответ 5

Вот еще одно возможное решение, если ни одно из других решений не будет работать для вас...

Попробуйте записать файл журнала в корень диска c. По умолчанию я установил log4net для записи в текущий каталог, который всегда является каталогом unit test, запущенным справа?... неправильно! Я запускаю Windows 8 с vs 2012, используя MS Unit Test, и записывает файл в локальный каталог temp, который удаляется после завершения unit test. В моей настройке он записывает файл здесь:

C:\Users\[myself]\AppData\Local\Temp\TestResults

В нижней строке, какие-либо юнит-тесты, которые я пишу сейчас, будут использовать полный путь к файлу журнала, а не относительный.