Mocking multiple interfaces

13 views
Skip to first unread message

Anders Gustavsson

unread,
Mar 18, 2025, 7:07:20 AMMar 18
to Spring4D
I have a class TMyClass = class(TInterfacedObject, InterfaceA, InterfaceB) and I want to mock this class in a situation where both interfaces are used.

I tried this approach

THybridClass = class(TInterfacedObject, InterfaceA, InterfaceB)
private
  FA: InterfaceA;
  FB: InterfaceB;
public
  constructor Create;
  property A: InterfaceA read FA implements InterfaceA;
  property B: InterfaceB read FB implements InterfaceB;
end;

constructor THybridClass.Create;
begin
  FA := Mock<InterfaceA>.Create;
  FB := Mock<InterfaceB>.Create;
end;

The testing does something like this:

var testobject: InterfaceA;

testobject := THybridClass.Create;

(testobject as InterfaceB)....

But this last line crashes with "interface not supported"

How can I fix this?

Stefan Glienke

unread,
Mar 18, 2025, 7:23:13 AMMar 18
to Spring4D
Your code confuses me a bit because you insert the mock into what seems to be the class you want to test.
I don't know what the production code of THybridClass looks like and if it provides additional functionality apart from what InterfaceA and InterfaceB provide.

Because otherwise there is most likely other code consuming and working with these interfaces where you can simply inject the mocked interfaces without the THybridClass shell.

Anyhow implementing additional interfaces into one mock is done via that AsType method. If you want to go back and forth between these two interfaces you need to implement them in the same mock instance like so:

constructor THybridClass.Create;
var
  mock: Mock<InterfaceA>;
begin
  FA := mock;
  FB := mock.AsType<InterfaceB>;
end;

Keep in mind though that if you now (and that was also the case before) are leaking the THybridClass if you create it because its lifetime is not managed by anything because it directly returns one of the mocked interfaces in its two fields.

As I said before, if your code to test consumes these two interfaces then directly use a mock like I wrote in that ctor but directly pass them to the code under test.

Anders Gustavsson

unread,
Mar 18, 2025, 8:20:19 AMMar 18
to Spring4D
No, this was not the class I tested, it was a class used in tested class! And your solution is of course correct! Thanks!
/Anders

Reply all
Reply to author
Forward
0 new messages