How do I test an interface? Should I even do that?


http://softwareonastring.com/2014/11/09/how-do-i-test-an-interface-should-i-even-do-that

Comments

  1. Very interesting - thanks for sharing!

    ReplyDelete
  2. Go the full way if you are using generics :)

    Create a base class once:

      TInterfaceTest = class(TTestCase)
      protected
        fSUT: TInterface;
        procedure SetUp; override;
      end;

    { TInterfaceTest }

    procedure TInterfaceTest.SetUp;
    begin
      fSUT := TImplementation.Create; // cool, that works because we can combine an interface and constructor constraint and make the one generic argument the constraint for the other one!
    end;

    and then you don't have to write any boilerplate code in your actual test:

      TSomeInterfaceContractTests = class(TInterfaceTest)
      published
        procedure SomeMethod_Input_EmptyString_ShouldReturn_False;
      end; // yes, we have to repeat the constraints here but nothing else, just write down the tests

    { TSomeInterfaceContractTests }

    procedure TSomeInterfaceContractTests.SomeMethod_Input_EmptyString_ShouldReturn_False;
    begin
      CheckEquals(fSUT.SomeMethod(''), False);
    end;

    But even if you go without that extra base class the cool thing is that you don't need to restrict your classes to be a TInterfacedObject but specify the interface they need to implement (yay, compiletime type safety) and then you can get rid of the Supports call and directly assign the result of the ctor call to the sut variable.

    ReplyDelete
  3. Stefan Glienke Nice! I have done something similar for a typed composite array where the constructor takes an interface and a class so that you can just call AddItem to have an instance added to the array. Hadn't made the connection yet with testing interfaces. I learn every day...

    ReplyDelete

Post a Comment