Unit Testing

46.1 DUnitX (Bundled, Modern)

File → New → Other → Unit Test → DUnitX Project. Runners: console, GUI (VCL), TestInsight (IDE plugin by Stefan Glienke, which runs tests inside the IDE).

Assertions: AreEqual, AreNotEqual, IsTrue, IsFalse, IsNull, IsNotNull, Contains, StartsWith, WillRaise, WillNotRaise, IsEmpty, InheritsFrom.

unit CalculatorTests;

interface

uses
  DUnitX.TestFramework, Calculator;

type
  [TestFixture]
  TCalculatorTests = class
  private
    FCalc: TCalculator;
  public
    [Setup]
    procedure Setup;
    [TearDown]
    procedure TearDown;

    [Test]
    procedure Add_TwoNumbers_ReturnsSum;

    [Test]
    [TestCase('Positive', '2,3,5')]
    [TestCase('Negative', '-2,-3,-5')]
    [TestCase('Zero', '0,0,0')]
    procedure Add_Cases(A, B, Expected: Integer);

    [Test]
    procedure Divide_ByZero_RaisesException;
  end;

implementation

procedure TCalculatorTests.Setup;
begin
  FCalc := TCalculator.Create;
end;

procedure TCalculatorTests.TearDown;
begin
  FCalc.Free;
end;

procedure TCalculatorTests.Add_TwoNumbers_ReturnsSum;
begin
  Assert.AreEqual(5, FCalc.Add(2, 3));
end;

procedure TCalculatorTests.Add_Cases(A, B, Expected: Integer);
begin
  Assert.AreEqual(Expected, FCalc.Add(A, B));
end;

procedure TCalculatorTests.Divide_ByZero_RaisesException;
begin
  Assert.WillRaise(procedure begin FCalc.Divide(1, 0); end, EDivByZero);
end;

initialization
  TDUnitX.RegisterTestFixture(TCalculatorTests);
end.

46.2 Mocks, Legacy DUnit and Testability

Mocking: Delphi-Mocks (VSoft), Spring4D Mocks (Mock<IService>). They require interfaces, so design with DI.

DUnit (legacy, xUnit-style TTestCase) is still found in older projects. DUnit2 is a fork.

Make code testable: separate business logic from forms (MVP/MVVM), depend on interfaces, avoid global state, and use data modules or repositories behind interfaces.

Code coverage: Delphi Code Coverage (open source), DUnitX + coverage. UI testing: TestComplete, Ranorex (commercial).