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?

有帮助吗?

解决方案

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top