[TestFixture]
public abstract class EntlibConfigurationTestBase
{
private ConfigXmlDocument configFile;
protected abstract IEnumerable<Category> Categories
protected abstract string ConfigFile { get; }
[OneTimeSetUp]
public void TestFixtureSetup()
{
configFile = new ConfigXmlDocument();
configFile.Load(ConfigFile);
}
[Test]
[TestCaseSource(nameof(Categories))]
public void CategoryShallHaveCorrespondingSectionInEntlibConfig(Category category)
{
var categorySources = configFile.GetElementsByTagName("categorySources").Cast<XmlElement>().Single();
var addNodes = categorySources.SelectNodes("add");
Assert.IsNotNull(addNodes);
var foundCategories =addNodes.Cast<XmlElement>().Select(x => x.GetAttribute("name")).ToHashSet();
Assert.IsTrue(foundCategories.Contains(category.ToString()), "Category {0} must be defined as source in {1}", category, ConfigFile);
}
[Test]
public void AllListenersMustBeDefined()
{
var listeners = configFile.SelectSingleNode("configuration/loggingConfiguration/listeners");
Assert.IsNotNull(listeners);
var addNodes = listeners.SelectNodes("add");
Assert.IsNotNull(addNodes);
var validListeners = addNodes.Cast<XmlElement>().Select(x => x.GetAttribute("name")).ToHashSet();
addNodes = categorySources.SelectNodes("add/listeners/add");
Assert.IsNotNull(addNodes);
var usedLiseners = addNodes.Cast<XmlElement>().Select(x => x.GetAttribute("name")).ToHashSet();
Assert.IsEmpty(usedLiseners.Except(validListeners).ToList());
}
}
public class ServerLoggingTest : EntlibConfigurationTestBase
{
protected override IEnumerable<Category> Categories
{
get { ... } // logic to find which categories are actually used by the server code
}
protected override string ConfigFile
{
get { return "EntlibServer.config"; }
}
}
public class ClientLoggingTest : EntlibConfigurationTestBase
{
protected override IEnumerable<Category> Categories
{
get { ... } // logic to find which categorie are actually used by the client code
}
protected override string ConfigFile
{
get { return "EntlibClient.config"; }
}
}
In this case working around it is to make test-method CategoryShallHaveCorrespondingSectionInEntlibConfig(Category category) virtual, and move the attributes to the subclasses, add an override and call the base implementation. That leads to code duplication in an undesirable, but at least manageable way. But I was wondering if there is a better solution that does not involve code duplication.