1

What would be the best way to create unit tests for testing the parameters I send to my WCF service?

I have a project where I have a repository class that speaks to my WCF service. It looks something like this:

public class MyRepository : IMyRepository
{
    public Customer GetCustomer(int customerId)
    {
        var client = new MyWCFServiceClient();
        MyWCFServiceCustomer customerWCF = client.GetCustomer(customerId);
        Customer customer = ConvertCustomer(customerWCF);
        return customer;
    }

    //Convert a customer object recieved from the WCF service to a customer of
    //the type used in this project.
    private Customer ConvertCustomer(MyWCFServiceCustomer customerWCF)
    {
        Customer customer = new Customer();
        customer.Id = customerWCF.Id;
        customer.Name = customerWCF.Name;
        return customer;
    }
}

(This is obviously simplified)

Now I would like to write unit tests to check that the parameters I send to my service from the repository is correct. In the example above it would be kind of pointless since I only send the customerId just as it is passed in, but in my real code there are more parameters and some more logic in the repository class.

The problem is that the generated service client class (MyWCFServiceClient) doesn't have an interface and so I can't mock it in my tests (or am I wrong about that?).

Edit: I was wrong about this. There is an interface! See my answer below.

One solution would be to have a class that wraps the service client and that only re-sends the parameters and returns the result:

public class ClientProxy : IClientProxy
{
    public MyWCFServiceCustomer GetCustomer(int customerId)
    {
        var client = new MyWCFServiceClient();
        return client.GetCustomer(customerId);
    }
}
public interface IClientProxy
{
    MyWCFServiceCustomer GetCustomer(int customerId);
}

That way I could give that class an interface and thus mock it. But it seems tedious to write that "proxy" class and keep it updated, so I was hoping you have a better solution! :)

haagel
  • 2,646
  • 10
  • 36
  • 53

2 Answers2

0

You should have a look at this post here

Instead of using the ServiceReference proxies (which are buggy anyway - Disposing the client always tries to close the connection, even if it is faulted), you can use the ClientBase<IServiceContract> directly.

You can either use proxied Service Contract interfaces created by the ServiceReference, or if you have control over both ends of the link, then you can build the ServiceContract interfaces into a separate assembly and share it on client and server.

Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • here's the issue I'm searching for: How do you get ClientBase to not construct a Channel when the constructor fires? I've pulled my client into an abstract class that brings in IService & ClientBase and then I can have a Controller use that as an injection point. In executing the unit test, when constructing a mock/fake, the ChannelFactory still looks for a configuration. Hmm maybe I'll do a try & empty catch on it. – Josh Robinson Jun 26 '13 at 17:23
0

My bad... there actually is an interface to the generated service class. I found it when looking some more. It just didn't have the name I expected it to have (in my example, if the client was called MyWCFServiceClient I expected the interface to be called IMyWCFServiceClient, but it was actually called IMyWCFService).

So I could just rewrite my controller to inject the service client and thus make it mockable:

public class MyRepository : IMyRepository
{
    private readonly IMyWCFService _serviceClient;

    //Constructor
    public MyRepository(IMyWCFService serviceClient)
    {
        _serviceClient = serviceClient;
    }

    public Customer GetCustomer(int customerId)
    {
        MyWCFServiceCustomer customerWCF = _serviceClient.GetCustomer(customerId);
        Customer customer = ConvertCustomer(customerWCF);
        return customer;
    }

    //Convert a customer object recieved from the WCF service to a customer of
    //the type used in this project.
    private Customer ConvertCustomer(MyWCFServiceCustomer customerWCF)
    {
        Customer customer = new Customer();
        customer.Id = customerWCF.Id;
        customer.Name = customerWCF.Name;
        return customer;
    }
}
haagel
  • 2,646
  • 10
  • 36
  • 53