I have number of classes I've been asked to add some unit tests to with Rhino Mocks and having some issues.
First off, I know RhinoMocks doesn't allow for the mocking of Static members. I'm looking for what options I have (besides using TypeMock).
An example of the class I have is similar to the below:
class Example1 : ISomeInterface
{
private static ISomeInterface _instance;
private Example1()
{
// set properties via private static methods
}
static Example1()
{
_instance = new Example1();
}
public static ISomeInterface Instance()
{
get { return _instance; }
}
// Instance properties
// Other Instance Properties that represent objects that follow a similar pattern.
}
So when I call the above class, it looks something like this...
Example1.Instance.SomeObject.GoDownARabbitHole();
Is there a way for me to mock out the SomeObject.GoDownARabbitHole()
in this situation or mock out the Instance?
Just use Reflection. With provided sample code you need to make sure the static constructor is called before setting the static field to the mocked object. Otherwise it might overwrite your mocked object. Just call anything on the singleton that has no effect before setting up the test.
It is not possible to inherit from a static class, while it is possible with singleton pattern if you want to allow it. So, anyone can inherit from a singleton class, override a method and replace the service. It is not possible to write an extension method to a static class while it is possible for a singleton object.
The static instance variable inside of a singleton is meant to hold the only instance of the class that will exist. It is static because it will need to be referenced by a static method 'GetInstance()' that will return the instance, or will create the instance if it is the first time that 'GetInstance()' was called.
It's very difficult to write unit tests for code that uses singletons because it is generally tightly coupled with the singleton instance, which makes it hard to control the creation of singleton or mock it.
Discouraged by threads like this, it took me quite some time to notice, that singletons are not that hard to mock. After all why are we using c#?
Just use Reflection.
With provided sample code you need to make sure the static constructor is called before setting the static field to the mocked object. Otherwise it might overwrite your mocked object. Just call anything on the singleton that has no effect before setting up the test.
ISomeInterface unused = Singleton.Instance();
System.Reflection.FieldInfo instance = typeof(Example1).GetField("_instance", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
Mock<ISomeInterface> mockSingleton = new Mock<ISomeInterface>();
instance.SetValue(null, mockSingleton.Object);
I provided code for mocking with Moq, but I guess Rhino Mocks is quite similar.
Singletons are at odds with Testability because they are so hard to change. You would be much better off using Dependency Injection to inject an ISomeInterface instance into your consuming classes:
public class MyClass
{
private readonly ISomeInterface dependency;
public MyClass(ISomeInterface dependency)
{
if(dependency == null)
{
throw new ArgumentNullException("dependency");
}
this.dependency = dependency;
}
// use this.dependency in other members
}
Notice how the Guard Claus together with the readonly
keyword guarantees that the ISomeInterface instance will always be available.
This will allow you to use Rhino Mocks or another dynamic mock library to inject Test Doubles of ISomeInterface into the consuming classes.
Here's a low-touch approach that uses a delegate, which can be set initially and changed at runtime. It's better explained by example (specifically, mocking DateTime.Now):
http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/11/09/systemtime-versus-isystemclock-dependencies-revisited.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With