Reputation: 2717
I have a static class wherein I am reading an XML to build a dictionary. Now this initialization is done in the static constructor.
In order to test this Initialize method, I have to somehow stub out the reading of XML logic and just give it an XDocument for testing, but not sure how can I do that.
internal static class MasterMnemonicsLookup
{
private static Dictionary<string, StateCoverageMnemonic[]> masterMnemonics = new Dictionary<string, StateCoverageMnemonic[]>();
private static StateCoverageMnemonic[] stateCoverageMnemonics;
static MasterMnemonicsLookup()
{
Initialize();
}
private static void Initialize()
{
var resource = XDocument.Parse(GetResourceTextFile("MasterMnemonics.xml"));
var serializer = new XmlSerializer(typeof (MasterMnemonicsType));
var model = (MasterMnemonicsType) serializer.Deserialize(resource.CreateReader());
var stateCoverageMnemonicsList = new List<StateCoverageMnemonic>();
foreach (var masterMnemonic in model.MasterMnemonics)
{
var stateCoverageMnemonicsXml = new List<StateCoverageMnemonic>();
var excludedStates = RiskStates.None;
StateCoverageMnemonic allStateCoverageMnemonic = null;
foreach (var stateCoverageMnemonic in masterMnemonic.StateCoverageMnemonics)
{
var state = stateCoverageMnemonic.StateCode;
if (!state.HasFlag(RiskStates.All))
{
excludedStates = excludedStates | state;
var mnemonic = stateCoverageMnemonic.Mnemonic;
var coverageCode = stateCoverageMnemonic.CoverageCode;
var stateCoverageMnemonicTemp = new StateCoverageMnemonic(state, mnemonic, coverageCode);
stateCoverageMnemonicsXml.Add(stateCoverageMnemonicTemp);
}
else
{
//// TODO: If All occurs twice should we throw an exception
allStateCoverageMnemonic = new StateCoverageMnemonic(state, stateCoverageMnemonic.Mnemonic, stateCoverageMnemonic.CoverageCode);
}
}
if (allStateCoverageMnemonic != null)
{
stateCoverageMnemonicsXml.Add(new StateCoverageMnemonic(RiskStates.All ^ excludedStates, allStateCoverageMnemonic.Mnemonic, allStateCoverageMnemonic.CoverageCode));
}
stateCoverageMnemonicsList.AddRange(stateCoverageMnemonicsXml);
masterMnemonics.Add(masterMnemonic.MasterMnemonic, stateCoverageMnemonicsXml.ToArray());
}
stateCoverageMnemonics = stateCoverageMnemonicsList.ToArray();
}
private static string GetResourceTextFile(string filename)
{
string result = string.Empty;
using (Stream stream = typeof(MasterMnemonicsLookup).Assembly.GetManifestResourceStream("Geico.Applications.Business.CoverageApi.DomainLayer.DataLayer." + filename))
{
var streamReader = new StreamReader(stream);
result = streamReader.ReadToEnd();
}
return result;
}
}
Upvotes: 0
Views: 190
Reputation: 430
I agree with Darious Vaughan-Scott
But if you want to keep using the static constructor you may want to put the loading logic into a seperate class which makes it easier to test.
For example
internal class MasterMnemonicsLoader
{
public void Load(
XDocument resource,
Dictionary<string, StateCoverageMnemonic[]> masterMnemonics,
StateCoverageMnemonic[] stateCoverageMnemonics)
{
//Do the loading here
}
}
and in the Initialize method you can call the Load method
private static void Initialize()
{
var resource = XDocument.Parse(GetResourceTextFile("MasterMnemonics.xml"));
var loader = MasterMnemonicsLoader();
loader.Load(resource, masterMnemonics, stateCoverageMnemonics);
Upvotes: 0
Reputation: 1095
Using static contructors in this way is not advised, and your scenario is a good example why. You might try the singleton pattern using a public instance constructor that accepts an XDocument. (You can use internal, but this makes it harder to unit test). This is a simple form of dependency injection.
For testing, an instance of your class can simply be created by your testing framework with the test XDocument.
For your live application, a static instance of your class can be initialized and held by a container type, and the appropriate XDocument can be passed in privately (within the container).
Upvotes: 2