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