The Straight Dope

Go Back   Straight Dope Message Board > Main > General Questions

Reply
 
Thread Tools Display Modes
  #1  
Old 12-08-2010, 12:23 PM
bup bup is offline
Guest
 
Join Date: Sep 1999
C# - Mocking Out a Web Service

For Unit Testing, I'd like to mock out web services that my app consumes.

From googling, I don't think it's possible for my web service (which is under my control) to implement an interface that is specified in the web reference.

Is there a clean pattern anybody knows of for replacing a real web service with a mock, for ease of testing?
Reply With Quote
Advertisements  
  #2  
Old 12-08-2010, 12:46 PM
friedo friedo is offline
Charter Member
 
Join Date: May 2000
Location: Brooklyn
Posts: 19,246
I'm not too familiar with the way C# does things, but in my work when we need to do this sort of thing, we generally make a class which implements the API for the web service, and which uses a HTTP client library (or SOAP, whatever) to do its thing. Then for unit testing we mock the HTTP client library, and leave the API class alone. Our mocked class then pretends to be a server and feeds HTTP responses back when requests are executed.
Reply With Quote
  #3  
Old 12-08-2010, 12:57 PM
bup bup is offline
Guest
 
Join Date: Sep 1999
So you just manually implement an interface that the compiler doesn't enforce?

So you have a service called TheService, for instance:

Code:
public partial class TheService: HttpClientProtocol
{
 public object func1(){}
 public object func2(){}
}
and an interface and implementation locally?
Code:
public interface IOurWrapper
{
 object func1(){}
 object func2(){}
}


public OurWrapper : IOurWrapper
{
   public TheService TheService;

   public object func1()
   {
     return TheService.func1();
   }

   public object func2()
   {
    return TheService.func2();
   }
}
I was hoping for something cleaner, but if that's what it is, that's what it is.
Reply With Quote
  #4  
Old 12-08-2010, 01:05 PM
LSLGuy LSLGuy is offline
Charter Member
 
Join Date: Sep 2003
Location: St. Louis, MO USA
Posts: 6,155
If you're consuming a traditional SOAP web service, then your code is typically interacting with the proxy class which Vis Studio (or WSDL.exe) generated for you. That proxy class is part of your project and under your control.

There's nothing to preclude you manually altering that proxy class to replace the real http calls with mocking code of your own. Then regenerate the proxy when you want to go live.

Or better yet, take a copy of the valid proxy proxy class & rename it, then alter it into a mock class. Then have your consuming code switch between using the real & the mock class by using a compiler variable to switch between embedding "using myRealProxyClass;" and "using myMockProxyClass;" statements in your consuming code.

In my experience consuming 3rd-party SOAP services, the biggest problem is that the wsdl / SOAP spec does a good job of defining the syntax of the interaction, but is real weak on semantics. So you can spend a lot of effort making a mock which reflects how you think the service works, but doesn't reflect how it really works, particularly in corner or error cases.

And so your code passes all your unit tests & still fails miserably in dealing with the other guys' quirks.

Last edited by LSLGuy; 12-08-2010 at 01:06 PM.
Reply With Quote
  #5  
Old 12-08-2010, 01:11 PM
LSLGuy LSLGuy is offline
Charter Member
 
Join Date: Sep 2003
Location: St. Louis, MO USA
Posts: 6,155
You can even go so far as to generate the proxy class into its own assembly. And also generate your mock proxy class into a separate assembly with the same namespace & class names.

Then you can test live or mock by controlling which physical dll file is present in the bin or GAC of your test environment.

I would strongly avoid the idea you coded above with a layer of interface to add another layer of abstraction to the proxy class. Just more opportunity for maintenance headaches in vNext.
Reply With Quote
  #6  
Old 12-08-2010, 02:26 PM
bup bup is offline
Guest
 
Join Date: Sep 1999
Quote:
Originally Posted by LSLGuy View Post
You can even go so far as to generate the proxy class into its own assembly. And also generate your mock proxy class into a separate assembly with the same namespace & class names.
Oohh...not bad. I shall consider that strongly.
Reply With Quote
  #7  
Old 12-08-2010, 04:37 PM
Khadaji Khadaji is offline
Member
 
Join Date: Mar 2002
Location: Southern Pennsylvania
Posts: 21,601
Stack Overflow is a good source for tech questions, and here is a link to a blog I found on that site.
Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 01:26 AM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

Send questions for Cecil Adams to: cecil@chicagoreader.com

Send comments about this website to: webmaster@straightdope.com

Terms of Use / Privacy Policy

Advertise on the Straight Dope!
(Your direct line to thousands of the smartest, hippest people on the planet, plus a few total dipsticks.)

Publishers - interested in subscribing to the Straight Dope?
Write to: sdsubscriptions@chicagoreader.com.

Copyright © 2013 Sun-Times Media, LLC.