9
\$\begingroup\$

I have a third party component that I am trying to write unit tests around. The problem is that I can't mock the object and there is no interface.

I decided to create an interface and a wrapper class calling into the code for the sake of mocking. I looked into the class definition that is generated by Visual Studio using the meta data and noticed a few things:

  • The class has two constructors (one takes a parameter)
  • The class inherits from IDisposable

My questions are:

  1. Does my implementation below look right?
  2. Did I handle the IDisposable implementation correctly in the proxy class?
  3. Do I need the second constructor in the proxy class since the interface does not support constructor definitions? I use dependency injection in my code and I assume unless I tell my DI framework to use the second constructor I don't really need it but I am not sure.

The meta data looks like (slimmed down version):

public class PopClient : IDisposable
{
    public const int DefaultPort = 110;
    public const int DefaultSSLPort = 995;

    public PopClient();
    public PopClient(AddressFamily addressFamily);
    public bool HasTimeStamp { get; }
    public List<string> Capability();
    public void Connect(string host);
    protected override void GetServerGreeting();
}

Based on the meta data, my interface looks like (after removing methods/properties/access modifiers that are invalid in an interface definition):

public interface IPopClient : IDisposable
{
    bool HasTimeStamp { get; }
    List<string> Capability();
    void Connect(string host);
    void ConnectSSL(string host);
}

Based on the interface, I then created the wrapper class:

public class PopClientProxy : IPopClient
{
    private readonly Pop3 pop3;

    public PopClientProxy()
        this.pop3 = new Pop3();

    public PopClientProxy(AddressFamily addressFamily)
        this.pop3 = new Pop3(addressFamily);

    public bool HasTimeStamp
        get { return pop3.HasTimeStamp; }

    public List<string> Capability()
        return pop3.Capability();

    public void Connect(string host)
        pop3.Connect(host);

    public void Dispose()
    {
        if (pop3 != null)
            pop3.Dispose();
    }
}
\$\endgroup\$
8
\$\begingroup\$

Congratulations! You have successfully utilized the object-oriented design pattern known as the Adapter Pattern. I think that looks perfectly good. Though, I wouldn't check pop3 for null in the Dispose() method as it will be guaranteed to not be null by the constructors and the readonly field modifier:

public void Dispose()
{
    pop3.Dispose();
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I'm by no means an expert about IDisposable, but isn't there a risk that the thread gets aborted while the constructor runs, and the object subsequently gets disposed by the garbage collector, in which case pop3 may be null ? \$\endgroup\$ – Suzanne Dupéron Jan 20 '14 at 23:13
  • 2
    \$\begingroup\$ If your constructor aborts, the constructor will throw an exception. pop3 will either be picked up by the garbage collector or, if it were null, won't matter, because the Dispose() won't get called because the full PopClient object isn't created and is a null value (the using statement won't call Dispose() on a null object). \$\endgroup\$ – Jesse C. Slicer Jan 20 '14 at 23:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.