5

I have a C# class that gets generated using the wsdl.exe tool that looks something like this:

public partial class SoapApi : System.Web.Services.Protocols.SoapHttpClientProtocol
{
    public SOAPTypeEnum AskServerQuestion()
    {
        object[] results = return this.Invoke("AskServerQuestion");
        return (SOAPTypeEnum) results[0];
    }
}

I have some thin wrapper code around this that keeps track of the result, etc. Is it possible to use any of the object mocking frameworks to make a fake SoapApi class and return predictable results for each of the calls to the thin wrapper functions?

I can't make the AskServerQuestion() function virtual because it's auto-generated by the wsdl.exe tool.

ryancerium
  • 631
  • 1
  • 5
  • 11

3 Answers3

5

The way I've accomplished this was to inject an ISoapApi instead, where the ISoapApi interface mimics the automatically generated SOAP API.

For your case:

public interface ISoapApi
{
    SOAPTypeEnum AskServerQuestion ();
}

Then, take advantage of the fact that the generated SoapApi class is partial, and add this in another file:

public partial class SoapApi : ISoapApi
{
}

Then, consumers should just take an ISoapApi dependency that can be mocked by any of the mocking frameworks.

One downside is, of course, when the SOAP api changes, you need to update your interface definition as well.

Pete
  • 11,313
  • 4
  • 43
  • 54
  • Thanks a lot, worked like a charm. I had to add some stuff because the generated class implemented another interface, but that was definitely the correct path to go down. – ryancerium Feb 02 '10 at 22:36
  • I wish that the wsdl tools for C# would automatically generate a service interface when *consuming* web services, to save us the trouble, but I've been unable to find any way to make it do that, sadly. – Pete Feb 02 '10 at 22:49
1

The class is partial so you could make the class implement an interface in the partial class part you write. You can then mock the interface.

DW.
  • 464
  • 3
  • 5
1

I worked out a technique that will work for the case where the class is non-partial. Suppose this is the original class:

// Generated class, can't modify.
public class SomeClass
{
    // Non-virtual function, can't mock.
    public void SomeFunc() { //... }
}

First, extract the interface from that class:

public interface ISomeClass
{
    void SomeFunc();
}

Now make a new class that inherits from both of the above:

public SomeClass2 : SomeClass, ISomeClass
{
    // The body of this class is empty.
}

Now you can use SomeClass2 in your program. It will behave the same as SomeClass. And you can mock ISomeClass.

dan-gph
  • 16,301
  • 12
  • 61
  • 79