Modify

Opened 7 years ago

Closed 5 months ago

Last modified 4 months ago

#5282 closed Feature Requests (wontfix)

Test fixtures do not support virtual inheritance

Reported by: tye.zdrojewski@… 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.

Attachments (0)

Change History (11)

comment:1 Changed 6 years ago by Gennadiy Rozental

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.

comment:2 Changed 6 years ago by Tye Z. <tye.zdrojewski@…>

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 in reply to:  2 Changed 6 years ago by Tye Z. <tye.zdrojewski@…>

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 Changed 2 years ago by Gennadiy Rozental

Resolution: wontfix
Status: newclosed

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 Changed 2 years ago by tye.zdrojewski@…

Resolution: wontfix
Status: closedreopened

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 Changed 5 months ago by Raffi Enficiaud

Milestone: To Be DeterminedBoost 1.65.0

comment:7 Changed 5 months ago by Raffi Enficiaud

Owner: changed from Gennadiy Rozental to Raffi Enficiaud
Status: reopenednew

comment:8 Changed 5 months ago by Raffi Enficiaud

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 Changed 5 months ago by Raffi Enficiaud

Resolution: wontfix
Status: newclosed

comment:10 Changed 5 months ago by Raffi Enficiaud

Milestone: Boost 1.65.0To Be Determined

comment:11 Changed 4 months ago by tye.zdrojewski@…

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.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Raffi Enficiaud.
The resolution will be deleted.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.