#5282 closed Feature Requests (wontfix)
Test fixtures do not support virtual inheritance
Reported by: | Owned by: | Raffi Enficiaud | |
---|---|---|---|
Milestone: | To Be Determined | Component: | test |
Version: | Boost 1.45.0 | Severity: | Problem |
Keywords: | Cc: |
Description
A typical use of fixtures for a test suite is to make it a subclass of the class under test (CUT) so that protected members can be accessed.
However, if the CUT has a virtual base class in its inheritance chain, the call to that class's constructor cannot be specified, because the fixture macros introduce another level of inheritance (sub-struct).
This means that we have to jump through some hoops to get to protected members.
It would be nice to have an argument to the FIXTURE macros that would allow the tester to specify some or all of the initialization list for the final class/struct in the inheritance chain.
Change History (11)
comment:1 by , 11 years ago
follow-up: 3 comment:2 by , 11 years ago
Ok, so if I have a class TestMe
...
class TestMe { protected: bool protectedValue = 0; int protectedMethod(int arg) { ... } void someProtectedBehavior() { ... } }
I will usually create a fixture as a subclass:
/** * Override methods to add test functionality */ class TestMeFixture : public TestMe { // override production behavior for testing void someProtectedBehavior() { ... } } BOOST_FIXTURE_TEST_SUITE( MyTestSuite, TestMeFixture ) BOOST_AUTO_TEST_CASE( test_top_level_values ) { int expected = 123; BOOST_CHECK_EQUAL(expected, protectedMethod(456)); // call protected method BOOST_CHECK(protectedValue); // get protected value ... } BOOST_AUTO_TEST_SUITE_END()
...which is far more concise than writing a subclass as separate from the fixture, which would force you to write all sorts of getters and setters and wrappers for protected members.
comment:3 by , 11 years ago
Sorry, I forgot to add that TestMe
extends another class:
class TestMe : public TestMeParent { protected: bool protectedValue = 0; int protectedMethod(int arg) { ... } void someProtectedBehavior() { ... } }
...which is fine. But if the inheritance is virtual, and TestMeParent
does not have a default constructor, then its constructor must be specified by every subclass at any level:
class TestMeParent { public: TestMeParent(int initValue) { ... } } class TestMe : public virtual TestMeParent { public: TestMe() : TestMeParent(678) // initializer required at every inheritance level { ... } }
This breaks my fixture arrangement, because the fixture is subclassed again by the fixture macros.
Hopefully I explained it clearly enough! :)
comment:4 by , 7 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
I am not sure what you recommend us to do in this case. I guess you will have to specialize your base class separately from fixture in this case.
comment:5 by , 7 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
The recommendation is right in the original post: "an argument to the FIXTURE macros that would allow the tester to specify some or all of the initialization list".
Is that not do-able for some reason?
comment:6 by , 5 years ago
Milestone: | To Be Determined → Boost 1.65.0 |
---|
comment:7 by , 5 years ago
Owner: | changed from | to
---|---|
Status: | reopened → new |
comment:8 by , 5 years ago
I do not get it: you are writing a fixture for being able to test protected members of TestMeParent
, and you do not want to specify the constructions of TestMeParent
inside your fixture.
OTOH, having an additional parameter passed to the BOOST_FIXTURE_TEST_SUITE
will not help you very far here: you will still need to initialize TestMeParent
in some way, and you will still need to forward whatever has been passed to the ctor of TestMe
to TestMeParent
.
It is a bit confusing, I am flagging this as not doing.
comment:9 by , 5 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:10 by , 5 years ago
Milestone: | Boost 1.65.0 → To Be Determined |
---|
comment:11 by , 5 years ago
you do not want to specify the constructions of TestMeParent inside your fixture
...as indicated in the description AND in the example, the virtual parent's init list is "required at every inheritance level". That would include the subclass created by the macro.
We are talking about VIRTUAL inheritance, not regular inheritance.
It is a bit confusing, I am flagging this as not doing.
Please do not close an issue because you are confused.
I am not sure I understand what the problem is. CUT is not a fixture. and why fixture needs virtual base classes is unclear. Please provide an example.