tags:

views:

748

answers:

2

This relates somewhat to:

http://stackoverflow.com/questions/24993/invalidoperationexception-while-creating-wcf-web-service-instance/1711550#1711550

I have a .NET C# class library (DLL) that calls a WCF web service. It seems like any .exe that calls that .DLL must now have the web service configurations in its .EXE.config file.

So for example, if I write an NUnit test, then do I have to update the NUnit.exe.config with the web-service parms. This seems like it could get very difficult to manage. Am I missing a big point here? Any shortcuts? If I have dozens of WCF services, and dozens of NUnit tests, it seems like my NUnit.exe.config would be horrendous.

Thanks,

Neal Walters

+5  A: 

No, you're not missing anything. In .NET, the configuration is by default left to the hosting app - in ASP.NET the web runtime and its config file - web.config.

In a class library, it's the hosting app that uses the class library which is responsible for providing the configuration through it's app.config (--> YourApp.exe.config after compilation).

On thing you could do is externalize the web.config sections for WCF into separate *.config files, and then reference those in your testapp.exe.config again:

  <system.serviceModel>
    <extensions configSource="extensions.config" />
    <behaviors configSource="behaviors.config" />
    <bindings configSource="bindings.config" />
    <client configSource="client.config" />
    <services configSource="services.config" />
  </system.serviceModel>

Unfortunately, you can only externalize configuration sections but not configuration section groups (and <system.serviceModel> is a configuration section group :-( so you can't externalize it globally).

Marc

marc_s
I think this makes sense. If I had 5 apps that all had tests in NUnit, then I could have extensionsApp1.config, behaviorsApp1.config, etc... But I would still need 5 config files for each web service - yikes.
NealWalters
+5  A: 

For unit test purposes, on the client side, you should be mocking the web service proxy interface, so that the client calls your mock without needing to have the rest of the system in place.

In the application, you may find it more convenient to pass parameters (like the address and binding) into the WCF layer explicitly programattically -- leaving it up to the application as to whether it uses its own configuration or not.


EDIT -- extending the first point.

The point of WCF is to take an interface and provide an implementation that is running somewhere else (through the Channel generic type). In unit testing, you want to be able to replace WCF-generated implementation to the interface with a local mock instead.

Isolate the use of Channel into a method that you can override or replace in the test harness, and which returns an object of the interface type. Then in unit tests, swap in your own method that returns the mock instead.

Exercising the full WCF connection -- and the small amount of hand-written code that can't be covered in unit testing -- is then part of the system or integration test stage.

Steve Gilham
Can you elaborate on that first sentence, not sure I even understand it. Are you saying I should do the plumbing myself and not use the auto-generated proxy at all? Still thinking about that idea.
NealWalters
Edited to elaborate as requested.
Steve Gilham
move the connections to an own class so that your dll has a single point of connection with the service, extract an interface from that class and mock that :)
zzzuperfly