2011-11-17 16 views
10

Mam test jednostkowy testujący działanie w moim kontrolerze, akcja zapisuje do log4net.Unit Test & Log4net

Po uruchomieniu akcji działa dobrze - pisze do log4net.

Jednak po uruchomieniu testu urządzenia akcja nie zapisuje w log4net, ale nie rzuca żadnego wyjątku.

Czy ktoś ma rozwiązanie?

+2

Po prostu zgaduję, ale czy w pliku app.config dodano niezbędne informacje konfiguracyjne log4net do projektu testu jednostkowego? – rsbarro

Odpowiedz

1

To jest twoja konfiguracja log4net. W tej chwili może to być plik web.config lub log4net.config w Internecie/bin. Musisz umieścić go we wspólnej lokalizacji i umożliwić jego wykrycie przez aplikację internetową i test. Lub musisz umieścić go w pliku unittest.project => app.config. Ale jeśli masz wiele projektów testowych, będzie to duplikowane w wielu miejscach. Ideałem byłoby umieszczenie go we wspólnym miejscu.

+0

Próbowałem wcześniej, ale rzuca to rozszerzenie: "Unit Test Adapter rzucił wyjątek: Inicjator typu dla" Microsoft.VisualStudio.TestTools.Diagnostics.EqtTrace "wyrzucił wyjątek Nie można zainicjować systemu konfiguracji Nierozpoznana sekcja konfiguracji log4net (././.). " – ParPar

+0

Mam również w moim odwołaniu testu urządzenia do log4net, aw jego assemblyInfo dodałem zespół: [assembly: log4net.Config.XmlConfigurator (ConfigFile = "App.config", Watch = true)] – ParPar

+0

Czy masz sekcję log4net? zdefiniowane? Illuminati

8

log4net nie rzucać wyjątki: http://logging.apache.org/log4net/release/faq.html

piśmie do dziennika na dysku lub w bazie danych w badanej jednostki jest przeciwny do zamierzonego; chodzi o automatyzację. Nie powinieneś sprawdzać dzienników przy każdym uruchomieniu testów.

Jeśli naprawdę potrzebujesz sprawdzić, czy wykonano połączenie, aby się zalogować, powinieneś wyśmiewać interfejs ILog i potwierdzić, że została wywołana odpowiednia metoda.

Jeśli używasz szyderczego schematu, jest to banalne. Jeśli nie, możesz utworzyć klasę TestLogger, która implementuje lub częściowo implementuje ILog i ujawnia dodatkowe właściwości, które pokazują, ile razy dana metoda została wywołana. Twoje asercje sprawdzą, czy metody zostały wywołane zgodnie z oczekiwaniami.

Oto przykład klasy należy testowany:

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(); 
    } 
    } 

i test (stosując Rhino.Mocks do mock 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))); 
    } 
    } 
+1

Jeśli celem aplikacji nie jest wygenerowanie dziennika, zapisanie testu jednostkowego w celu sprawdzenia, czy rejestracja nastąpiła, to tylko wyciek szczegółowych informacji o implementacji do testu. Zachowanie testowe, a nie implementacja. – bryanbcook

+0

@bryanbcook Czy zgadzasz się lub nie zgadzasz z odpowiedzią? – Jay

+0

Sądzę, że jestem bardziej zainteresowany tym pytaniem, ponieważ nie chciałbym promować pisania testów jednostkowych, które potwierdzałyby rejestrację. – bryanbcook

3

warto dodać:

[assembly: log4net.Config.XmlConfigurator()] 

Do AssemblyInfo.cs (lub init log4net w inny sposób). Uznało tę odpowiedź here

19
// 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"); 

nie zrobić potrzeba aby dodać kolejną warstwę zadnie za pomocą interfejsu logowania (jeśli nie chcesz). Od lat używam abstrakcji, ale teraz idę w kierunku używania właśnie MemoryAppender, ponieważ testuje to, co faktycznie się dzieje. Po każdym teście pamiętaj o .Clear() the appender.

1

Oto kolejny możliwym rozwiązaniem, jeśli żaden z innych rozwiązań pracować dla Ciebie ...

Spróbuj napisać plik dziennika do katalogu głównego dysku C. Domyślnie ustawiłem log4net tak, aby zapisywał się do bieżącego katalogu, który jest zawsze katalogiem, w którym test jednostki działa od prawej? ... źle! Używam Windows 8 z vs 2012 przy użyciu MS Unit Test, i zapisuje plik do lokalnego katalogu tymczasowego, który zostaje usunięty po zakończeniu testu jednostkowego.W mojej konfiguracji pisze to plik tutaj:

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

Konkluzja wszelkie testy jednostkowe piszę do tej pory, zamierzamy wykorzystać pełną ścieżkę bezwzględną pliku dziennika i nie względnym.

+2

Dlaczego? Cały ten wątek jest bardzo dziwny. Log4net zapewnia możliwość, od razu po wyjęciu z pudełka, bez potrzeby operacji we/wy lub korzystania z mocków, w celu wykonania prostych testów opartych na stanie, ale każdy chce zrobić to na swój sposób. Dziwaczny. Wygląda na to, że użytkownicy logują się tylko na dysku. Log4net jest abstrakcją, więc możesz logować się do tego, co chcesz: przechowywanie tablic w azure ... 0Mq .. strumień twitter ... ... arrrrggh to bezcelowe !!!! Wszyscy po prostu logują się na dysku w twoich testach i utrudniają ci życie. : P – RhysC