Re: Instantiating an abstract class
On Oct 16, 10:07 pm, Salt_Peter <pj_h...@yahoo.com> wrote:
Soory but we don't 'hack' here.
The intent was to hack and then encapsulate, so in projects that use
this you get the benefit without the hacking. I'm trying to get this
as portable as possible regardless of the hacking and up to now it
seems to port very well.
If your AbstractInterface is pure abstract, then why not derive from
that to provide an Interface type. Your project can then use that
Interface and you the original AbstractInterface to derive that mock
type. Makes sense to me since the mock doesn't need the virtual
functions. It remains to be seen whether the following fullfills
requirements.
Sounds good, but the abstract interface's constructor won't be called.
A small adjusted example to show what we've accomplished so far:
class Interface
{
public:
virtual void foo() const = 0;
};
int main()
{
MockRepository mocks;
Interface *concrete = mocks.newMock<Interface>();
mocks.ExpectCall(concrete, Interface::foo);
mocks.ReplayAll();
concrete->foo();
mocks.VerifyAll();
}
Given just the interface above, this works already. The point is that
the Interface object isn't constructed per se, so if it contains any
nontrivial member (std::string, other object of sorts) those will not
be initialized properly and will make the mock behave differently from
the original. That's why the question popped up.
What we're trying to accomplish:
class Interface
{
public:
virtual std::string foo(std::string) const = 0;
std::string name;
};
int main()
{
MockRepository mocks;
Interface *concrete = mocks.newMock<Interface>();
concrete->name = "hello world";
mocks.ExpectCall(concrete, Interface::foo).Returns(concrete->name);
mocks.ReplayAll();
cout << concrete->foo();
mocks.VerifyAll();
}
The concrete->name calls the assignment operator on an unconstructed
string because the Interface constructor (auto-generated which calls
the std::string constructor) was not called. We can't find any way of
making that std::string constructed, other than abusing a subclass.
I understand that this isn't regular C++ but it would make the
language much more testable if it were possible. In particular, the
strict pure virtual semantics prevent this from working.
If the mock of Interface could call its constructor before working
around it, that would work fine. It can't do that, unless you first
create a subclass of it without pure virtual functions (like
ConcreteInterface) which then can be overridden again in the mocking
code. ConcreteInterface serves no other purpose in that construction
other than making the constructor accessible. Since it's such a lot of
code to write (for each test, create a full blank implementation for
each interface you want to mock) compared to what it's use is (make
the constructor - that already exists! - accessible) I would like to
find a workaround.
Thanks in advance,
Peter Bindels