guyl
guyl

Reputation: 2242

Build a class that can be tested

i have a class that uses a proxy class inside to call a service that provide data. of course if the method create the proxy inside there is a problem to test that class. do you think that the proxy should be given in the constructor even if it can be created inside without "knowing" ?

Upvotes: 0

Views: 78

Answers (3)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236308

You should provide class dependencies to class via dependency injection (constructor, property, parameter). That makes your class testable and allows to mock all those dependencies.

UPDATE: Inject service proxy:

class Foo
{
   private IServiceProxy _serviceProxy;
   public Foo(IServiceProxy _serviceProxy)
   {
        _serviceProxy = serviceProxy;
   }

   public void Bar()
   {
       var staff = _serviceProxy.GetStaff();
   }
} 

Btw consider to hide information about proxy from your class. E.g. implement by proxy same interface that actual service has and provide IService to your class.

UPDATE2 (gateway):

All our domain needs - to get some staff. So, we define interface:

interface IStaffService
{
  Staff GetStaff();
}

Our domain class (your tested class uses only this interface and does not depend on web services, proxy creation and other infrastructure concerns).

Next create Gateway (see definition on Martin Fowler site) for your service:

public MyServiceProxyGateway : IStaffService
{
    public Staff GetStaff()
    {
       var proxy = new YourProxyType();
       proxy.X = value;
       proxy.Y = value;
       var response = proxy.CallActualServiceMethod();
       Staff staff = new Staff();
       staff.Value = response.Something;
       return staff;
    }
} 

Your code now completely unaware about all this infrastructure communications. And you use handy interface GetStaff instead of CallActualServiceMethod.

Upvotes: 1

Oliver
Oliver

Reputation: 45109

To test my proxy classes i normally give the target that should be proxied within the constructor. Thous giving me the possibility to give a stub object for testing.

public class MyProxy : IProxiedInterface
{
    private IProxiedInterface _Target;

    public MyProxy(IProxiedInterface target)
    {
        if(target == null)
            throw new ArgumentNullException("target");

        _Target = target;
    }

    // ToDo: Implement all functions from IProxiedInterface
    //       and delegate them to the target
    public bool DoSomething()
    {
        return _Target.DoSomething();
    }
}

Upvotes: 1

Alex
Alex

Reputation: 8116

Well, there's a difference between "the proxy class knows how to instantiate itself" and "the class knows how to instantiate the proxy class". The second makes unit testing alot harder(if not impossible) if you pack that knowledge inside.

I'd use dependency injection (either via a framework,constructor or property) to take that knowledge to the caller - and make it testable.

Upvotes: 1

Related Questions