Question

Je me demande quelle est la meilleure façon d'initialiser log4Net dans un projet NUnit.Bien sûr, je veux appeler le code d'initialisation (c.-à-d. XmlConfigurator.Configure()) dès que possible pour obtenir autant de sorties de journaux précoces que possible.Mais comme mon projet est exécuté via NUnit, j'ai peu de contrôle sur son point d'entrée.

Selon la documentation NUnit, il doit d'abord appeler certains constructeurs, puis une méthode marquée du [SetUp] attribut dans une classe marquée par [TestFixtureSetup].

Donc, d’abord, j’ai créé une classe d’assistance statique que je peux appeler plusieurs fois sans problème.

  public static class LoggingFacility
  {
    private static bool _loggerIsUp = false;

    public static void InitLogger()
    {
      if (_loggerIsUp == false)
        XmlConfigurator.ConfigureAndWatch(f);

      _loggerIsUp = true;
    }
  }

Ensuite, j'ai fait tout mon [TestFixtureSetup] hériter d'un seul qui ne fait pratiquement rien d'autre que d'appeler LoggingFacility.initLogger().Mais cela laisse toujours tous les constructeurs exécutés plus tôt, dans un ordre que je ne peux que supposer aléatoire.Et de plus, il effectuera probablement quelques initialisations statiques avant même de pouvoir exécuter du code.

En fait, comme je peux le voir dans mon journal, les 4 premières secondes environ de l'exécution ne sont absolument pas enregistrées.

Est-ce que ça veut dire que je devrai appeler mon InitLogger() dans chaque constructeur et interdire l'utilisation de tout initialiseur statique ?C'est un travail difficile !

Est-ce que quelqu'un connaît un tour de magie avec ça ?

Était-ce utile?

La solution 2

Un compagnon de travail m'a fourni avec la solution de contournement suivante, qui fait le travail:

Dans toutes mes classes nécessitant une journalisation, j'ai eu l'initialisation de l'enregistreur suivante

private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Je l'ai simplement changé à un initialiseur singleton

private static readonly ILog Log = LoggingFacility.GetLoggerWithInit(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

/*** ... ***/

public static class LoggingFacility
{
  private static bool _loggerIsUp = false;

  public static ILog GetLoggerWithInit(Type declaringType)
  {
    if (_loggerIsUp == false)
      XmlConfigurator.Configure(_log4NetCfgFile);
    _loggerIsUp = true;
    return LogManager.GetLogger(declaringType);
  }
}

Parce que j'ai ce code dans chaque classe, cet initialiseur statique doit être appelé très tôt par Nunit Wile instanciant mes cours de test.

L'étape suivante consiste à faire en sécurité ce fil: (

Autres conseils

Pour un point d'initialisation unique, vous devez utiliser la classe marquée par [SetUpFixture] attribut et méthode marqués d'un [SetUp], Par exemple:

[SetUpFixture]
public class TestsInitializer
{
    [SetUp]
    public void InitializeLogger()
    {
        LoggingFacility.InitLogger();
    }
}

Maintenant, cette méthode ([SetUp] InitializeLogger) fonctionnera avant tout test est exécuté, le même que celui marqué d'un [TearDown] s'exécutera une fois tous les tests exécutés.Mais voici le piège : qu'est-ce que n'importe lequel et tous tu veux dire dans ce contexte ?Tests des cours déclaré dans le même espace de noms que la classe marquée avec [SetUpFixture].

Par exemple, en supposant une hiérarchie comme celle-ci :

- Tests
--- Business
----- TestsInitializer.cs // SetUpFixture class
----- FirstBusinessTests.cs
----- SecondBusinesTests.cs
--- ComplexLogic
----- VeryComplexLogicTests.cs

First et SecondBusinessTests va courir après SetUp depuis TestsInitializer, cependant VeryComplexLogicTests pourrait s'exécuter dans un ordre aléatoire.

Selon documentation liée, si vous déclarez SetUpFixture classe en dehors de tout espace de noms, la configuration et le démontage s'appliqueront à l'ensemble de l'assemblage :

Un seul SetUpFixture doit être créé dans un espace de noms donné.Un SetUpFixture en dehors de tout espace de noms fournit SetUp et TearDown pour l'ensemble de l'assembly.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top