Montag, 1. Juni 2009

Spring.Testing.NUnit, ConfigLocations und die App.config

Bei dem Versuch, Integrationstests unter Zuhilfenahme von Spring's Spring.Testing.NUnit  zu schreiben stand ich vor folgendem Problem:

Spring.Testing.NUnit wurde gegen eine ältere NUnit-Version kompiliert - daher war ein Assembly-redirect in der App.config nötig (unschön, denn nun hab ich eine App.config für eine dll):
   1: <runtime>
   2:      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
   3:        <dependentAssembly>
   4:          <assemblyIdentity name="nunit.framework"
   5:                        publicKeyToken="96d09a1eb7f44a77"
   6:                        culture="neutral"/>
   7:          <bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="2.4.3.0"/>
   8:        </dependentAssembly>
   9:        <dependentAssembly>
  10:          <assemblyIdentity name="Common.Logging" publicKeyToken="af08829b84f0328e"/>
  11:          <bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="2.0.0.0"/>
  12:        </dependentAssembly>
  13:      </assemblyBinding>
  14:    </runtime>

Am Rande: Wie die Zeilen 10 und 11 benutze ich für Spring die neue Common.Logging Version. Laut Dokumentation muss man nun lediglich die Integrationstestklasse von AbstractTransactionalDbProviderSpringContextTests ableiten und ConfigLocations angeben, die Spring dann zur Contextinstanziierung verwendet - und schon hat man zurückrollende Transaktionen am Ende eines jeden Tests. Meine ConfigLocations sahen zunächst so aus:
protected override string[] ConfigLocations
{
   get { return new string[]{ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath };
}
}

Diese wurde dann mit einer Exception zur Laufzeit geahndet:

failed: Spring.Objects.Factory.ObjectDefinitionStoreException : Error registering object defined in 'file [IntegrationTests\bin\Release\IntegrationTests.dll.temp.config] at line 3' : There is no parser registered for namespace ''

Die ersten Zeilen der Konfiguration sehen so aus:
   1:  <?xml version="1.0" encoding="utf-8" ?>
   2:  <configuration>
   3:    <configSections>
   4:      <sectionGroup name="common">

Die übrigen Zeilen der Konfiguration beinhalten die üblichen Spring Sections: spring, parsers, context, objects. Nach langer Suche hatte ich's dann: die ConfigLocation sieht nun so aus:
   1: protected override string[] ConfigLocations
   2: {
   3:  get { return new string[]{ "config://spring/objects" };  }
   4:  }

So hat man schlussendlich beides mit nur einer Konfigurationsdatei: AssemblyRedirection durch die App.config und normale Spring-Configsections. Glücklicherweise sind die beiden Namespaceparser DatabaseNamespaceParser und TxNamespaceParser offenbar automatisch registriert, sodass es nicht weiter ins Gewicht fällt, dass die parsers-Section nicht ausgewertet wird. Für nicht registrierte Namespace Parser bleibt schließlich noch das programmatische Registrieren in der XmlParserRegistry.

Keine Kommentare: