Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I unit test my WCF client class?

I have a class library that interacts with a WCF service, and uses an app.config file for its configuration. I'd like to unit test this class, but when I run my unit test, I get:

Could not find default endpoint element that references contract 'FooService' in the service model client configuaration section. This might be because no configuration file was found for your application or because no end point element matching this contract could be found in the client element

According to this answer, I need the app.config file to reside within my unit test project, and indeed this solves the problem. But I really don't want to have to copy my app.config file around to unit tests every time I change it.

I suppose I could add a link to the app.config, except that I'm using SlowCheetah to handle app.config transformations, so my app.config is generated at compile time.

Is there anything I can do to get this to work, or do I just have to give up on my app.config and handle the configuration in code?

like image 523
Eric Avatar asked Aug 20 '12 16:08

Eric


People also ask

How do I run a WCF test Client?

From the main menu, click DEBUG > Start Without Debugging. This starts the service and invokes the WCF Test Client window.


2 Answers

You can mock the WCF service in your tests. You can inject a version of the the service that doesn't use a WCF service when you are unit testing the class. This way, when the tests run, they don't need to worry about any configuration files. This is also going to lead to a better tests. Presumably you want to test your code, not the WCF service itself. It's better to mock it's behaviour in your tests so you can test only your code.

like image 156
Oleksi Avatar answered Oct 23 '22 10:10

Oleksi


Create a client wrapper, I did the same thing previously doing a ChannelLocator<T> that implemented IChannelLocator<T> and underneath it mostly wrapped a channel factory's behavior.

However be very careful that this abstraction is not leaking connections underneath, the ChannelFactory's channel management mechanisms are complex and should be studied carefully to avoid leaking client or server channels which may make either of them unresponsive.

Remember this pattern:

try
{
  yourChannel.Close();
}
catch
{
  yourChannel.Abort();
}

Then in your unit test, you merely Mock<IChannelLocator<T>> and you can create a great deal more scenarios in your code for instance you can test how your code responds when the client makes a request and get's a timeout exception, etc. Furthermore this will make your tests run exceedingly fast and on anyone's machine with no configuration because your test no longer depends on an actively running service.

What happens if that actively running service has a bug causing the unit test to fail, or worse pass inaccurately? It's a little more work to wrap your dependencies in abstraction layers for testing, but completely worth the trouble.

like image 31
Jimmy Hoffa Avatar answered Oct 23 '22 12:10

Jimmy Hoffa