Domanda

I am trying to decouple existing code to be able to unit test it. I have introduced interfaces to remove the dependency on UI objects.The problem is that the Spring container's RegisterComponent < T > call requires a TComponentType parameter, so I cannot call RegisterComponent< IMyProgressBar > I have to call RegisterType < TMyProgressBar >.Implements < IMyProgressBar > which means I have to use the unit containing the progressbar class definition in DUnit which defeats the purpose of using the DIContainer in concert with the ServiceLocater to ask for a progressbar whenever I need one.

I don't want to have to create mock classes and implement the interfaces manually. Is there a way to use Delphi.Mocks to automatically mock an interface without specifying the implementing class?

È stato utile?

Soluzione

You apparently do not use the latest version of Spring4D as this feature has been implemented last november (see the update in https://stackoverflow.com/a/11315141/587106)

Currently there is no auto mocking of the container but I like the idea and will look into implementing something that makes this easier (possibly by improving the container extension).

At the moment a test case method would look like this (using DSharp mocks syntax):

procedure TMyTestCase.TestSomething;
var
  progressBarMock: Mock<IProgressBar>;
  sut: TTestComponent;
begin
  container.RegisterType<TTestComponent>;
  container.RegisterType<IProgressBar>.DelegateTo(
    function: IProgressBar
    begin
      Result := progressBarMock;
    end);
  container.Build;

  // mock setup

  sut := container.Resolve<TTestComponent>;

  // perform test
end;

Anyway I highly suggest writing unit tests without the use of a DI container.

If your SUT has many dependencies making the use of the container appealing that is often a sign of violating certain design principles.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top