Make it simpler : get rid of Mocking Fx
In the wake of Rinat Technology Demons, I’d add Mocking frameworks to the list.
There are several reasons to do that.
Stubs
One of the usage of Mocking - or isolation – frameworks is stubbing. A component that access external resources or has complex behavior will be changed for a fake to have simpler predictable results.
- When the component interface is small, the stub declaration code is often more complicated that writing a fake implementation directly.
- When the interface has many methods, it makes things easier, but here you’ll ignore a code smell. It makes things easy in situation you should not reach !
There are also easy patterns that make the use of mocking irrelevant. A common one is configuration loading.
Lots of developers think: “I need a class to access my configuration. Let’s make a class for this”:
public class Configuration
{
public string EndPoint
{
get { return ConfigurationManager.AppSettings["EndPoint"]; }
}
// other properties here//
}
Then they realize they’ll have to isolate from ConfigurationManager, so they add a interface :
public interface IConfiguration
{
string EndPoint { get; }
}
public class Configuration : IConfiguration
{
public string EndPoint
{
get { return ConfigurationManager.AppSettings["EndPoint"]; }
}
// other properties here//
}
And they can moke the configuration using a lot of boring code.
what about this ?
public class Configuration
{
public string EndPoint { get; set; }
// other properties here//
}
public class ConfigurationLoader
{
public Configuration Load()
{
return new Configuration
{
EndPoint = ConfigurationManager.AppSettings["EndPoint"]
// other properties here//
};
}
}
Passing a different configuration in your test is a simple new Configuration {}… and you can use the ConfigurationLoader class in you main function.
A good thing here, is that you don’t suffer a read of the configuration file at each call without needing to introduce lazy loading or other tweaks that make things worse..
Mocks
When you need to see if a call happened, you can make an implementation of the interface that takes a lambda :
public interface IFancyService
{
void DoSomething(int arg);
}
public class MockFancyService : IFancyService
{
private Action<int> doSomething;
public MockFancyService(Action<int> doSomething)
{
this.doSomething = doSomething;
}
public void DoSomething(int arg)
{
doSomething(arg);
}
}
public class Test
{
void DoSomthingHasBenCalled()
{
bool wasCalled = false;
var fancyService = new MockFancyService(i => { wasCalled = true; });
var compoenent = new ComponentThatUseFancyService(fancyService);
compoenent.MakeSomething();
Assert.That(wasCalled, Is.True);
}
}
Or make the fake class record the call, and add a getter to check. It’s not that complicated.