Hi all
Just wanted to announce that I've released a beta-version of my WCF Extensions Library on my CodePlex project called Renewal Projects. Check out the documentation section for more info. I think WCF users in the .NET space may want to have a look at this as it might prove useful in the long run as it contains a Channel Repository, Channel Pool and the possibility to have WCF channels hosted in a IOC container.
Its in BETA at the moment but testers are welcome to try it out.
http://renewalprojects.codeplex.com/
Lessons, knowledge snippets and personal growth, all fine tuned by God's hands and redeemed through Christ's work on the cross for all to see and share.
Showing posts with label WCF. Show all posts
Showing posts with label WCF. Show all posts
Wednesday, November 09, 2011
Wednesday, August 17, 2011
Moles, WCF and IDisposable
We all have heard of the Moles tool which Microsoft released some time ago which allows one to stub any Type with a custom one (which substitutes the behavior of the original one) for the purpose of writing unit tests a bit easier. I did wonder some time ago if one could use this to stub WCF proxies so that you don't have to create a stubbed service hosts and make changes in your App.config, etc.
Initially it seemed like a dud but when I left it for a while and came back to it later I discovered that the solution is simple but not so obvious. I am not going to cover the basics of Moles, you can google that for yourself, I'm going to cover the necessary steps to get your WCF proxies (or whatever similar case) stubbed for unit testing purposes.
The problem that I had with Moles and WCF was that the proxy classes inherited from ClientBase (which wasn't the problem) which in turn inherited from IDisposable. Now since a proxy's constructor tries to check the configuration file for proxy configuration, I had to sub the constructor of that proxy with an empty delegate. I managed to stub the proxy call with something that returned a dummy value and running through the tests, it actually stubbed that proxy call which is what I wanted.
This was fine but I had a couple of proxies wrapped around a 'using' statement and at the end of a using statement the proxy's Dispose() method gets called and I got greeted with a nice NullReferenceException. I realised it was because I stubbed the constructor but when I checked for the Dispose method to stub, I couldn't find it anywhere in the generated Moled-Proxy class. That's the part that messed me around.
After some thinking and some Googling I started to think that I might have to "mole" the System.ServiceModel assembly in order to stub the Disposable method found in the ClientBase<> class. This also had a minor problem. It caused a compiler error but after some Googling someone recommended that I amend the 'System.ServiceModel.moles' file with the following:
Beneath the <Assembly> tag just add the following:
When you compile the unit test project it should finally generate the moled System.ServiceModel assembly and now we can finally stub that method! Now suppose you had a proxy which had the contract of IGeneral, you would stub its Disposable method like so:
Unfortunately you cannot just specify the MClientBase<> without specifying a Type. It will give a compiler error.
So by using an example unit test:
You should be able to successfully run it and stubbing the proxy call for your unit test to work.
the 'using' block should actually be the part where the production code gets executed but for demonstration purposes, I left it as is so that you can get the idea that the proxy gets stubbed as it should.
Here is the rest of the code for some clarity:
Initially it seemed like a dud but when I left it for a while and came back to it later I discovered that the solution is simple but not so obvious. I am not going to cover the basics of Moles, you can google that for yourself, I'm going to cover the necessary steps to get your WCF proxies (or whatever similar case) stubbed for unit testing purposes.
The problem that I had with Moles and WCF was that the proxy classes inherited from ClientBase (which wasn't the problem) which in turn inherited from IDisposable. Now since a proxy's constructor tries to check the configuration file for proxy configuration, I had to sub the constructor of that proxy with an empty delegate. I managed to stub the proxy call with something that returned a dummy value and running through the tests, it actually stubbed that proxy call which is what I wanted.
This was fine but I had a couple of proxies wrapped around a 'using' statement and at the end of a using statement the proxy's Dispose() method gets called and I got greeted with a nice NullReferenceException. I realised it was because I stubbed the constructor but when I checked for the Dispose method to stub, I couldn't find it anywhere in the generated Moled-Proxy class. That's the part that messed me around.
After some thinking and some Googling I started to think that I might have to "mole" the System.ServiceModel assembly in order to stub the Disposable method found in the ClientBase<> class. This also had a minor problem. It caused a compiler error but after some Googling someone recommended that I amend the 'System.ServiceModel.moles' file with the following:
Beneath the <Assembly> tag just add the following:
<StubGeneration>
<Types>
<Clear/>
<Add Namespace="System.ServiceModel.Description!"/>
</Types>
</StubGeneration>
When you compile the unit test project it should finally generate the moled System.ServiceModel assembly and now we can finally stub that method! Now suppose you had a proxy which had the contract of IGeneral, you would stub its Disposable method like so:
MClientBase<IGeneral>.AllInstances.SystemIDisposableDispose = (c) => { };
Unfortunately you cannot just specify the MClientBase<> without specifying a Type. It will give a compiler error.
So by using an example unit test:
[TestMethod]
[HostType("Moles")]
public void TestMethod1()
{
MGeneralProxy.AllInstances.GetName = (p) => "Stubbed Name";
MGeneralProxy.Constructor = (p) => { };
MClientBase<IGeneral>.AllInstances.SystemIDisposableDispose = (c) => { };
using (GeneralProxy p = new GeneralProxy())
{
Assert.AreEqual("Stubbed Name", p.GetName());
}
}
You should be able to successfully run it and stubbing the proxy call for your unit test to work.
the 'using' block should actually be the part where the production code gets executed but for demonstration purposes, I left it as is so that you can get the idea that the proxy gets stubbed as it should.
Here is the rest of the code for some clarity:
public interface IGeneral
{
string GetName();
}
public class GeneralService : IGeneral
{
public string GetName()
{
return "General Name";
}
}
public class GeneralProxy : ClientBase<IGeneral>, IGeneral
{
public string GetName()
{
return Channel.GetName();
}
}
Subscribe to:
Posts (Atom)