unit test static constructor w/ different config values - c#

I have a class with a static constructor which I use to read the app.config values. How do I unit test the class with different configuration values. I'm thinking of running each test in different app domain so I can have static constructor executed for each test - but I have two problems here:
1. I do not know how to run each test run in separate app domain and
2. how do I change configuration settings at run time?
Can someone please help me with this? Or anyone has a better solution? Thanks.

Personally I would just stick your static constructor into a static method then execute that method in the static block.

You don't need to test .Net being able to load data from config files.
Instead, try to concentrate on testing your own logic.
Change your class so that it gets the configuration values from its constructor (or via properties), and then test it as you would with any other dependency.
Along the way you have also moved your class towards SRP.
As per the configuration loading - concentrate this logic in a separate, non-static class.
EDIT:
Separate the configuration logic into another class. something like this:
public static class ConfigurationLoader
{
static ConfigurationLoader()
{
// Dependency1 = LoadFromConfiguration();
// Dependency2 = LoadFromConfiguration();
}
public static int Dependency1 { get; private set; }
public static string Dependency2 { get; private set; }
}
Then, when you instantiate your class, inject it with the dependencies:
public class MyClass
{
private readonly int m_Dependency1;
private readonly string m_Dependency2;
public MyClass(int dependency1, string dependency2)
{
m_Dependency1 = dependency1;
m_Dependency2 = dependency2;
}
public char MethodUnderTest()
{
if (m_Dependency1 > 42)
{
return m_Dependency2[0];
}
return ' ';
}
}
public class MyClassTests
{
[Fact]
public void MethodUnderTest_dependency1is43AndDependency2isTest_ReturnsT()
{
var underTest = new MyClass(43, "Test");
var result = underTest.MethodUnderTest();
Assert.Equal('T', result);
}
}
...
var myClass = new MyClass(ConfigurationLoader.Dependency1, ConfigurationLoader.Dependency2);
You could go on and use IOC containers, but your problem of testing MyClass with different inputs is solved by this simple testable design.

If you read from (Web)ConfigurationManager.AppSettings, that is just a NameValueCollection, so you can replace your code that reads ConfigurationManager.AppSettings directly with code, that reads from any NameValueCollection.
Just move out your actual configuration parsing to a static method from the static ctor. Static ctor calls that static method and passes ConfigurationManager.AppSettings, but you can call that parser method from the test code, and verify the config parsing without actually touching a file, or messing with appdomains.
But on the long run, really inject your configuration parameters as seldary suggested. Create a configuration class, read the actual values at application start, and set up your IoC container to supply the same configuration instance to all requesters.
This makes further testing easier too, because you classes don't read from a global static configuration instance. You can just pass in a specific configuration instance for differet tests. Of course create a factory method for your tests, to construct a global configuration, so you don't have to do it manually all the time...

I had the same exact problem recently. The only difference was that the configuration value was coming from database instead of app.config. I was able to resolve it using TypeInitializer.
[Test]
public void TestConfigurationInStaticConstructor()
{
// setup configuraton to test
// ...
// init static constructor
ReaderTypeInit();
// Assert configuration effect
// ...
// reset static ctor to prevent other existing tests (that may depend on original static ctor) fail
ReaderTypeInit();
}
// helper method
private void ReaderTypeInit()
{
typeof(< your class with static ctor>).TypeInitializer.Invoke(null, new object[0]);
}

Related

How can you use dependency injection when creating an object inside of a static method?

I have a class with several static methods that is being used in a CLR SQL stored procedure method. I ended up writing a wrapper with non-static methods that implements an interface of the methods I want.
I'm doing this so that I can write a unit test. However, the unit test is for a static method that also has another dependency that I can't figure out how to work around.
Note: CLR Stored Procedures need to be static.
public class MyHelperWrapper : IMyHelper
{
public void DoStuff(List<MyObject> list)
{
MyHelper.DoStuff(list); // Static method that sends data to database.
}
}
public class FakeMyHelperWrapper : IMyHelper
{
public void DoStuff(List<MyObject> list)
{
// don't do anything??
}
}
public class MyCLRClass
{
public static void My_Stored_Proc(string a, string b)
{
MyPrivateStaticMethod(a, b);
}
private static void MyPrivateStaticMethod(string a, string b)
{
List<MyObj> list = new List<MyObject>();
MyObject obj = new MyObject(a, b);
list.Add(obj);
MyHelperWrapper.DoStuff(list); // MyWrapper is wrapped around the static methods of the class MyHelper
}
private static string Format(string b)
{
// ... format ...
return bFormatted;
}
}
At the end of the day, I guess I really just need to test that the method creates a new object based on the parameters a and b and then adds it to a list.
My issues:
The method is void so what's the proper way to even test this? Just make sure no errors happen?
If I'm injecting fake classes (such as a fake MyHelperWrapper) then I'm basically bypassing a bunch of the code. This seems bad to me?
If I were to continue this route, how can I inject a fake class for MyObject? This seems kind of bad because then I'm not testing that the object is created how I expect.
Is there a better way? Maybe I have to refactor MyObject to use DI as well but this all seems kind of hacky just to test that an object is added to a list.
The way I resolved this was by injecting the dependency (that was causing the issue) into the constructor of MyObject.

C# code timing in production

I wish to implement switchable code timing facilities in my production code, the idea being that when performance issues are occurring on a user machine the performance logging can be turned on to provide useful data to indicate where issues are.
To this end my logic would be to have a factory class that would implement a bool property TrackPerformance and a method GetPerformanceTracker that returns either of NullPerformanceTracker or LoggingPerformanceTracker that implement an IPerformanceTracker interface.
The Null is obviously there to do nothing and the other would write out to a Log4Net logger which could potentially be split out from the normal logging if required. I'd use the StopWatch class for timings. So far so good.
The issue?
How best to implement this without it overly affecting performance itself?
I'm thinking of using compiler services attributes on a MarkElapsedTime method as
MarkElapsedTime(string message, [CallerMemberName] callerMemberName = "", [CallerLineNumber] int = 0)
Instantiating a timer at method level seems sub-optimal due to the number of factory calls. It therefore seems to be preferable to instantiate this at a class level, in which case I need to tie the MarkElapsedTime call to the relevant Start() call in order to measure the correct amount of elapsed time.
Loosely
class LoggingPerformanceTracker:IPerformanceTracker
{
private readonly ILog mLogger = LogManager.GetLogger(....);
private readonly StopWatch mStopWatch = new StopWatch();
private readonly Dictionary<int, TimeSpan> mElapsed = new Dictionary<int, TimeSpan>();
private int mNextId = 0;
public void MarkElapsedTime(int timerId, string message, [CallerMemberName] callerMemberName = "", [CallerLineNumber] int = 0)
{
var ts = mStopWatch.Elapsed.Subtract(mElapsed[timerId]);
if (mLogger.IsInfoEnabled)
mLogger.Info(string.Format("{0}: {1} - [{2}({3})]", message, ts, callerMemberName, callerLineNumber));
}
public int Start()
{
if (!mStopWatch.IsRunning)
mStopWatch.Start();
var key = mNextId;
mNextId++;
mElapsed.Add(key, mStopWatch.Elapsed);
return key;
}
}
I've not had to do this before and given that these measurement calls would be placed all over the codebase in key areas I'd ideally like to get it right first time.
Also is the use of the Log4Net logger a good or bad idea - I obviously need to see the data at some point whether that means logging in memory then dumping or sending to file straight off.
So here's how to do some dependency injection to solve this issue.
First, let's just say we have this code:
public class DoSomeWork
{
public void Execute()
{
Console.WriteLine("Starting");
Thread.Sleep(500);
Console.WriteLine("Done");
}
}
It's piece of code that performs some (potentially) long running task.
We might call it like this:
static void Main(string[] args)
{
var doSomeWork = new DoSomeWork();
doSomeWork.Execute();
Console.ReadLine();
}
Now, to add logging I could go thru the code base and add code like this:
public class DoSomeWork
{
public void Execute()
{
var sw = Stopwatch.StartNew();
Console.WriteLine("Starting");
Thread.Sleep(500);
Console.WriteLine("Done");
Console.WriteLine(sw.ElapsedMilliseconds);
}
}
But this means that if I want to add logging code to the entire code base I'm editing a lot of files and making my code more complicated.
There is a way to make this work without adding the logging code to each file.
To start with we need to introduce an interface with the Execute method to abstract the code we're calling.
public interface IDoSomeWork
{
void Execute();
}
Now the DoSomeWork class looks like this:
public class DoSomeWork : IDoSomeWork
{
public void Execute()
{
Console.WriteLine("Starting");
Thread.Sleep(500);
Console.WriteLine("Done");
}
}
Now the calling code looks like this:
static void Main(string[] args)
{
var context = Context.CreateRoot();
context.SetFactory<IDoSomeWork, DoSomeWork>();
var doSomeWork = context.Resolve<IDoSomeWork>();
doSomeWork.Execute();
Console.ReadLine();
}
Now, I've used a dependency injection framework that I wrote for this, but you could use Castle Windsor, Ninject, etc.
The line Context.CreateRoot() creates a dependency injection container. The context.SetFactory<IDoSomeWork, DoSomeWork>() configures the container to know that when I ask for an instance of IDoSomeWork to actually return an instance of DoSomeWork.
The line var doSomeWork = context.Resolve<IDoSomeWork>() asks to container to try to resolve (create or return) an instance of an object that implements IDoSomeWork.
From there the code runs like the original code.
Now I can write a logging class that "decorates" the concrete class.
public class DoSomeWorkLogger : IDoSomeWork, IDecorator<IDoSomeWork>
{
public void Execute()
{
var sw = Stopwatch.StartNew();
this.Inner.Execute();
Console.WriteLine(sw.ElapsedMilliseconds);
}
public IDoSomeWork Inner { get; set; }
}
This class implements IDoSomeWork as well as a special interface IDecorator<IDoSomeWork> required by my container to allow this class to act as a decorator.
So now the calling code looks like this:
static void Main(string[] args)
{
var context = Context.CreateRoot();
context.SetFactory<IDoSomeWork, DoSomeWork>();
context.SetDecorator<IDoSomeWork, DoSomeWorkLogger>();
var doSomeWork = context.Resolve<IDoSomeWork>();
doSomeWork.Execute();
Console.ReadLine();
}
The line context.SetDecorator<IDoSomeWork, DoSomeWorkLogger>() now tells the container that there is a decorator for the IDoSomeWork interface.
So what now happens when the line var doSomeWork = context.Resolve<IDoSomeWork>() is called is that an instance of DoSomeWork is created like before, but also an instance of DoSomeWorkLogger is created. The Inner property of the DoSomeWorkLogger instance is set with the instance of the DoSomeWork and the DoSomeWorkLogger instance is returned from the Resolve method.
So now when the doSomeWork.Execute() method is call then the logger code is run which in turn calls the actual execute code.
The DoSomeWork code doesn't need to change for me to add the logging functionality.
Now this code as it stands isn't perfect yet as we have all of the SetFactory and SetDecorator code that would create dependencies that we want to avoid.
So here's how we get around it.
First the IDoSomeWork, DoSomeWork, and DoSomeWorkLogger code are moved into three separate assemblies.
Then DoSomeWork and DoSomeWorkLogger have two special attributes added. They look like this:
[Factory(typeof(IDoSomeWork))]
public class DoSomeWork : IDoSomeWork { ... }
[Decorator(typeof(IDoSomeWork))]
public class DoSomeWorkLogger : IDoSomeWork, IDecorator<IDoSomeWork> { ... }
Now I can change the calling code to this:
static void Main(string[] args)
{
var config = XDocument.Load(#"fileName");
var context = Context.LoadRoot(config);
var doSomeWork = context.Resolve<IDoSomeWork>();
doSomeWork.Execute();
Console.ReadLine();
}
The container is now configured using an XML file. The format of the XML isn't important, but what is is that it can be changed without recompiling the code. So by changing the XML to not include the assembly that the DoSomeWorkLogger class is defined in will effectively remove the logging. Add that assembly and instantly the logging code is added back in with no recompilation necessary.
Simple. :-)

instance class->static class->instance class in C#

I have done a lot of reading on instance vs. static classes and have not found an answer to my question. Are there any perils to instancing a different class in a static class that was referenced by an instance class?
The current design I am working with is one in which instance classes call a static "Logger" method (passing a series of parameters) to log errors to a text file in the file system. I am refactoring the static "Logger" method to instantiate a parameter class (which is just a series of properties and a few helper methods to return itself as XML or a string) and a DBLogger class to log the error to the database rather than the file system, passing the parameter class as the sole parameter.
This model worked well in my legacy VB6 code, in which the Logger class was instanced, not static.
But now in the .NET code I am not sure if I should make my 2 new classes (parameter and DBLogger) static, or just make the DBLogger static and instance the parameter class. I am concerned about the potential for concurrency/multi-thread data issues with (or without) instances being created from a static class. Am I right to be concerned or am I worrying about nothing?
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
// all code truncated for illustration purposes
namespace ThisIs.A.Test
{
//INSTANCE
public class ErrorLogParameters
{
private int mThreadId = 0;
private int mErrorNumber = 0;
private string mServerDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
public int ThreadId
{
get { return mThreadId; }
set { mThreadId = value; }
}
public int ErrorNumber
{
get { return mErrorNumber; }
set { mErrorNumber = value; }
}
public string ServerDate
{
get { return mServerDate; }
}
}
//INSTANCE
public class ErrorLog
{
public void LogErrorToDatabase(ErrorLogParameters criteria)
{
//Log error to database here
}
}
//STATIC - Instantiates INSTANCE of ErrorLogParameters and ErrorLog
public class Logger
{
public static void WriteLog(string pstrObjectName, string pstrProcedureName, int plngErrNumber, string pstrErrDescription)
{
// create a new parameter object
ErrorLogParameters objParameters = new ErrorLogParameters();
// populate object properties
objParameters.ErrorNumber = mlngErrNumber;
objParameters.ThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
ErrorLog objErrorLog = new ErrorLog();
objErrorLog.LogErrorToDatabase(objParameters);
}
}
//INSTANCE - Invokes STATIC method
public class SomeInstance
{
private void ErrorHandler_Log(Exception exception, string procedureName, string additonalDescription, string stackTrace)
{
// call from instance class to static class
Logger.WriteLog(mstrObjectName, procedureName, mlngErrNumber, mstrErrDescription);
}
}
}
No, that's absolutely fine - if you're creating an instance of any class within a method, it doesn't matter whether the class declaring that method is a static class or not.
Furthermore, unless you've got something "special" (e.g. a static variable counting the number of instances created) you're less likely to run into concurrency issues when creating new objects than when using existing objects. Basically, the tricky part of almost all concurrency is working out where mutable data is shared - it doesn't sound like you've got any here (although sample code would help to clarify that).
I would use a combination of the provider and singleton pattern for this.
Create an abstract class called Logger.
The Logger class contains abstract methods for writing to log. For example:
abstract void LogInfo(LogInfo info);
abstract void LogError(Exception exception);
etc
The Logger class contains a private instance of Logger object.
The Logger class contains a static property that returns the private instance.
The Logger class contains a static constructor that instantiate the private instance of Logger object. You would probably use Reflection and instantiate the object based on the configuration.
Implement a FileLogger that inherits from the Logger object. This logger writes to a file.
Implement a SQLLogger that inherits from the Logger object. This logger writes to a database.
Call the logger like so:
Logger.Instance.WriteInfo(info);
Logger.Instance.WriteError(exception);
There are a few advantages of using this design:
Your logging functionality is fully abstracted. This completely decouple the logging callers from the code that writes the logs. This allows you to write the log to any data stores.
You can change which logger to use without compiling the code. Just update the config file.
Singleton guarantees thread-safety
Testability. You can write Mock tests against abstract classes.
Hope this helps.
There are no concurrency issues with static methods.
Static variables are a different matter.

Implementation Problem with Static Sealed Class

I have a Sealed class in C#, which already exists and all methods are static.
It does some file operations with xml file. The file name till today was hardcoded into source.
Now the requirement needs to keep it in Configuration file.
The problem is:
Since class is extract, i need to expose some static 'Initialize' method to assign filename to some local static filename variable, which will replace hardcoded string.
So, i always have to make sure, Initialize is called first and then later method.
So, the better way is to have constructor, which i cant write.
I want a better way to do this ensuring type safety.
If the filename field is static, you could make it a property or method and make sure the getter does the work of initializing it from the configuration file if it is not already initialized...
That way you don't have to explicitly initialize the class via a method you can have the access to the property itself initialize the value.
Something like below..
static string FileName { get { return (_field ?? _field = GetFileName()); } }
static string GetFileName() { /* TODO: Return filename from config */ }
Why can't you use a static constructor?
You could write a static constructor to initialize your paths before the static members are referenced.
More info can be found here
If the class itself doesn't know how to access the config I'd use a one time setter:
private static string _filename;
public static string Filename
{
get
{
if(_filename==null)
throw new InvalidOperationException("Filename not set");
return _filename;
}
set
{
if(_filename!=null)
throw new InvalidOperationException("Filename set twice");
_filename=value;
}
}
Or if the class can access the config directly it's even easier:
private static readonly string Filename;
static MyClassName()
{
Filename=GetFilenameFromConfig();
}
Just initialize it in a static constructor.
Assuming the configuration file path is known (i.e. the class takes no formal arguments), then a static constructor might help.
You could change your current class from something like:-
public static Foo
{
public static void Execute()
{
const string FileName = "foo.xml";
// ...
}
}
To something like
public static Foo
{
public static void Execute()
{
Execute("foo.xml");
}
public static void Execute(string fileName)
{
// ...
}
}
Current clients of the code can continue to use the original method (hard coded file name) and any new clients which have the file name as a configuration item can use the new method which takes the file name as a parameter. Or, if you have decided that all client should use the new method, then you can change them to do that and remove the old method.
The simplest option would be to add a static constructor. That will be executed before any other code:
public static class Foo
{
static Foo()
{
// Initialization code
}
// Other methods which can depend on initialization code having run
}
As I say, this is the simplest - in terms of changes to your existing code. However, code like this tends to be hard to debug, and if you have a lot of static constructors which depend on each other, you can get into some tricky situations (particularly if you have cyclic dependencies). For an example of this, watch the "C# Puzzlers" video from NDC 2010 - an excellent talk given by Eric Lippert and Neal Gafter.

C# Static constructors design problem - need to specify parameter

I have a re-occurring design problem with certain classes which require one-off initialization with a parameter such as the name of an external resource such as a config file.
For example, I have a corelib project which provides application-wide logging, configuration and general helper methods. This object could use a static constructor to initialize itself but it need access to a config file which it can't find itself.
I can see a couple of solutions, but both of these don't seem quite right:
1) Use a constructor with a parameter. But then each object which requires corelib functionality should also know the name of the config file, so this has to be passed around the application. Also if I implemented corelib as a singleton I would also have to pass the config file as a parameter to the GetInstance method, which I believe is also not right.
2) Create a static property or method to pass through the config file or other external parameter.
I have sort of used the latter method and created a Load method which initializes an inner class which it passes through the config file in the constructor. Then this inner class is exposed through a public property MyCoreLib.
public static class CoreLib
{
private static MyCoreLib myCoreLib;
public static void Load(string configFile)
{
myCoreLib = new MyCoreLib(configFile);
}
public static MyCoreLib MyCoreLib
{
get { return myCoreLib; }
}
public class MyCoreLib
{
private string configFile;
public MyCoreLib(string configFile)
{
this.configFile = configFile;
}
public void DoSomething()
{
}
}
}
I'm still not happy though. The inner class is not initialized until you call the load method, so that needs to be considered anywhere the MyCoreLib is accessed. Also there is nothing to stop someone calling the load method again.
Any other patterns or ideas how to accomplish this?
You need a common location to store this. You could use the app.config even if this is a seperate assembly by defining a config section in the library assembly and referencing it you proceess app.config. Or you could just add a generic setting to appSettings and reference that without using strongly typed settings. If the value is user entered then you could use isolated storage.
Finally you could put it in a well known location in the registry at install time.
For code the following is encapsulted better
public interface ICoreLib
{
void SomeMethod();
}
public static class CoreLibManager
{
private static ICoreLib coreLib;
private static volatile bool initialized;
private static readonly object lockObject = new object();
public static ICoreLib CoreLib
{
get
{
Inititialize();
return coreLib;
}
}
/// <summary>
/// The inititialize.
/// </summary>
private static void Inititialize()
{
if (initialized)
{
lock (lockObject)
{
if (!initialized)
{
string configFile = // Fech from common location
coreLib = new MyCoreLib(configFile);
initialized = true;
}
}
}
}
/// <summary>
/// The my core lib.
/// </summary>
private class MyCoreLib : ICoreLib
{
public MyCoreLib(string configPath)
{
}
public void SomeMethod()
{
}
}
}
When you have global state like this that you need to initialize and it requires outside input to complete initialization (such as a config file), then you're stuck with the outside code that knows about the input having to call Load or Initialize to initialize your global state. There's no way around this.
The issue that you've correctly observed, however, is that anybody could try to use the global state before it has been properly Initialized, which is the downside to having it exposed in this way. The way you get around this is by refactoring all of the stateful parts of your global library into an instance class and passing references to that instance through your application. Because you control when it is created and initialized, you can now ensure it has valid state before you pass it along. You trade off the convenience of global state for the better insulation you're after.
You can use the .net configuration system to do this. The simplest way to do this is to use the <appsettings> element in your web.config file, or in your appname.exe.config file. Use:
ConfigurationManager.AppSettings["property_name"]
to access a property. Whether your code is running in a web context or as a windows app, the configuration system will find the config file and load the values you need.
You can also build a more complex system with type-safe config values and hierarchical data, but my needs were pretty simple, so I didn't explore this after the first headache set in :)
You could make the class a singleton, thus ensuring there's only ever one instance of it while also allowing for the constructor parameter.
There won't be much alternatives.
Either you pass stuff around (in that case I'd not pass the string around but create a concrete (non-static) CoreLib and pass that around or you do what you suggested.
Don't forget to hide the constructor for MyCoreLib. Currently it is public which is likely unintended.
OK, thanks everyone for your assistance. I've refactored the CoreLib project and broken out the config handling into a separate project. Now we have a solution-wide shared class for config management. The class can take care of itself with a user setting, which is exposed via the static property ConfigFile. This property also persists the modified file location if the user changes via some config dialog. Also the initialized flag will be reset if the config file changes.
public interface IConfig
{
void SomeMethod();
}
public static class ConfigurationManager
{
private static IConfig config;
private static volatile bool initialized;
private static readonly object lockObject = new object();
public static string ConfigFile
{
get { return Properties.Settings.Default.ConfigFile; }
set
{
if (Properties.Settings.Default.ConfigFile == value) return;
lock (lockObject)
{
Properties.Settings.Default.Save();
initialized = false;
}
}
}
public static IConfig Config
{
get
{
Inititialize();
return config;
}
}
private static void Inititialize()
{
lock (lockObject)
{
if (initialized) return;
config = new Configuration(Properties.Settings.Default.ConfigFile);
initialized = true;
}
}
}
internal class Configuration : IConfig
{
public ClientConfig(string configFile)
{
// Parse & validate config file
}
public void SomeMethod()
{
}
}
So now in the start-up we first validate the persisted ConfigFile setting, then attempt to access the Configuration instance via the manager's Config property. Any parsing exceptions can be handled here and dealt with accordingly. Then it is up to the developer to handle any exceptions for IConfig's methods.
if (!System.IO.File.Exists(ConfigurationManager.ConfigFile))
{
// Display config file locator dialog
ConfigurationManager.ConfigFile = someDialog.FileName;
}
try
{
IConfig config = ConfigurationManager.Config;
}
catch
{
// Error parsing config file
}

Categories