1

I testing a class to manage Lockbox 3. I have the following pseudo mock:

unit uMockTPWDDBManager;

interface

uses inifiles,classes,UITypes,uTPLb_Codec;

type
  IPWDDBManager = interface
    ['{51C993FE-D96A-4419-AB80-00D65E16C6F8}']
  end;

  ICodec = interface
    ['{B1858F24-5B76-4468-8BD5-55684EA43CCD}']
    function GetPassword:string;
    procedure SetPassword(const c:string);
    property Password:string read GetPassword write SetPassword;
end;

  TPWDDBManager=class(TIniFile,IPWDDBManager)
  private
    FCodec1: ICodec;
    FRefCount: Integer;
  protected
    function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  public
    constructor Create(const FileName: string; Fcodec: ICodec);virtual;
    property RefCount: Integer read FRefCount;
  end;

  TMockCodec1 = class(TCodec,ICodec)
  private
    function GetPassword:string;
    procedure SetPassword(const c:string);
  end;


implementation

uses spring.container;

{ TMockCodec1 }

function TMockCodec1.GetPassword: string;
begin
  result:=Password;
end;

procedure TMockCodec1.SetPassword(const c: string);
begin
  password:=c;
end;

{ TPWDDBManager }

constructor TPWDDBManager.Create(const FileName: string; Fcodec: ICodec);
begin
  inherited create(FileName);
  FCodec1:=Fcodec;
//  FCodec1.Password:= 'ABC';
end;

function TPWDDBManager.QueryInterface(const IID: TGUID; out Obj): Integer;
const
  E_NOINTERFACE = $80004002;
begin
  if GetInterface(IID, Obj) then
    Result := 0
  else
    Result := E_NOINTERFACE;
end;

function TPWDDBManager._AddRef: Integer;
begin
  Inc(FRefCount);
  Result := FRefCount;
end;

function TPWDDBManager._Release: Integer;
begin
  Dec(FRefCount);
  if FRefCount = 0 then
  begin
    Destroy;
    Result := 0;
    Exit;
  end;
  Result := FRefCount;
end;

initialization
  GlobalContainer.RegisterComponent<TMockCodec1>.Implements<ICodec>;
  GlobalContainer.RegisterComponent<TPWDDBManager>.Implements<IPWDDBManager>;
end.

and the following unit test:

unit TestuTPWDDBManager;
{

  Delphi DUnit Test Case
  ----------------------
  This unit contains a skeleton test case class generated by the Test Case Wizard.
  Modify the generated code to correctly setup and call the methods from the unit
  being tested.

}

interface

uses TestFramework,uMockTPWDDBManager,IniFiles;

type
  // Test methods for class TPWDDBManager
  TestTPWDDBManager = class(TTestCase)
  strict private
    FCodec1: ICodec;
    FPWDDBManager: IPWDDBManager;
  public
    procedure SetUp; override;
  published
    procedure TestGetPWD;
  end;

implementation

uses SysUtils,Spring.container,Spring.Services;

procedure TestTPWDDBManager.SetUp;
begin
  GlobalContainer.Build;
  FCodec1:=ServiceLocator.GetService<ICodec>;
//  FCodec1:=TMockCodec1.Create(nil);
  FCodec1.Password:='a';
  FPWDDBManager :=TPWDDBManager.Create('',FCodec1);
end;


procedure TestTPWDDBManager.TestGetPWD;
begin
end;

initialization
  // Register any test cases with the test runner
  RegisterTest(TestTPWDDBManager.Suite);
end.

when I run the test I have an error message on the line FCodec1.Password:='a';

If I replace FCodec1:=ServiceLocator.GetService<ICodec>; with FCodec1:=TMockCodec1.Create(nil); then no error on FCodec1.Password:='a';

It seems the ServiceLocator didn't create the TmockCodec1 class in this case.

Where am I doing wrong ?

pio pio
  • 732
  • 1
  • 7
  • 29
  • Although this is not an answer to your question, it is worth noting that LB3 comes with an extensive suite of unit tests using the DUnit framework. You may be trying to create unit tests that have already been developed. – Sean B. Durkin Nov 03 '13 at 22:39
  • I have checked the unit tests shipped with LB3 but didn't find anything that involves interfaces and Dependency Injection – pio pio Nov 03 '13 at 23:41

0 Answers0