7

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?

Community
  • 1
  • 1
Eric
  • 5,842
  • 7
  • 42
  • 71
  • 1
    The unit tests should not care about the app.config because each class should be tested in isolation to the rest of the solution. Have you imported the projects reference into the test solution? – Clinton Ward Aug 20 '12 at 17:00
  • 1
    It's true you need to copy your web.config to the test project's app.config. What I've done to simplify this is create a separate .config file for the service model section and link to it from all the .config's that need to use it. That way I can make changes in one place for the entire solution. – Forty-Two Aug 20 '12 at 17:04
  • @Forty-Two, that sounds like a good solution, although for me, I don't think I'd be able to use config transforms in that scenario. – Eric Aug 20 '12 at 17:06
  • Does your client have a constructor overload where you can pass in the connection information? – cadrell0 Aug 20 '12 at 17:13

2 Answers2

5

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.

Oleksi
  • 12,947
  • 4
  • 56
  • 80
1

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.

Jimmy Hoffa
  • 5,909
  • 30
  • 53