Default constructor required?

1,630 views
Skip to first unread message

Michael Jeung

unread,
Jun 4, 2009, 7:53:32 PM6/4/09
to Google C++ Mocking Framework
Hi,

I have a feeling that I'm doing something wrong with my mocks:

MockHouse inherits from House. House does not define a default
constructor: House() doesn't exist.

House's constructor looks like this:
House(Windows, Doors, Kitchens, LivingRooms, BedRooms, BathRooms,
Garages, Attics, Basements)

In other words, there are a lot of objects that House depends on.

When I instantiate the MockHouse in my test, I don't want to have to
pass all of these objects into it, since it makes it painful to set up
the mock.

Do I need to explicitly define a House() function in my production
code? If I don't have one, I get this error: "no matching function
call for House::House()"

-Michael

Zhanyong Wan (λx.x x)

unread,
Jun 4, 2009, 8:05:49 PM6/4/09
to Michael Jeung, Google C++ Mocking Framework

What you really need is a default ctor for MockHouse. If the base
class House has a default ctor, the compiler can generator a default
ctor for MockHouse and you are all set. Otherwise you need to define
the default ctor yourself.

Therefore, you can define a default ctor either for House or for
MockHouse. Either way, MockHouse will get a default ctor.

>
> -Michael
>

--
Zhanyong

Michael Jeung

unread,
Jun 5, 2009, 12:42:34 PM6/5/09
to Google C++ Mocking Framework
On Jun 4, 5:05 pm, Zhanyong Wan (λx.x x) <w...@google.com> wrote:
> On Thu, Jun 4, 2009 at 4:53 PM, Michael Jeung <jeungs...@gmail.com> wrote:
> > Do I need to explicitly define a House() function in my production
> > code?   If I don't have one, I get this error: "no matching function
> > call for House::House()"
>
> What you really need is a default ctor for MockHouse.  If the base
> class House has a default ctor, the compiler can generator a default
> ctor for MockHouse and you are all set.  Otherwise you need to define
> the default ctor yourself.
>
> Therefore, you can define a default ctor either for House or for
> MockHouse.  Either way, MockHouse will get a default ctor.


I see. But what if House has a reference data member that must be
initialized during construction?

For instance:

class House
{
public:
House( DB_Connection & db_connection );
House( );

private:
DB_Connection & m_db_connection;
}

House::House( DB_Connection & db_connection ) : m_db_connection
( db_connection )
{
}

House::House( )
{
}

This second constructor will not compile since the m_db_connection
data member is not being initialized.

I suppose I could solve this by making m_db_connection a pointer and
then having the default constructor initialize the pointer to NULL -
but now it seems like I'm making changes to my production code simply
for the sake of making the mock easier to build.

Thoughts?

Thanks!
-Michael

Zhanyong Wan (λx.x x)

unread,
Jun 5, 2009, 12:46:45 PM6/5/09
to Michael Jeung, Google C++ Mocking Framework
On Fri, Jun 5, 2009 at 9:42 AM, Michael Jeung <jeun...@gmail.com> wrote:
>
> On Jun 4, 5:05 pm, Zhanyong Wan (λx.x x) <w...@google.com> wrote:
>> On Thu, Jun 4, 2009 at 4:53 PM, Michael Jeung <jeungs...@gmail.com> wrote:
>> > Do I need to explicitly define a House() function in my production
>> > code?   If I don't have one, I get this error: "no matching function
>> > call for House::House()"
>>
>> What you really need is a default ctor for MockHouse.  If the base
>> class House has a default ctor, the compiler can generator a default
>> ctor for MockHouse and you are all set.  Otherwise you need to define
>> the default ctor yourself.
>>
>> Therefore, you can define a default ctor either for House or for
>> MockHouse.  Either way, MockHouse will get a default ctor.
>
>
> I see.  But what if House has a reference data member that must be
> initialized during construction?

If that's your choice, House's default ctor should take care of
initializing the reference member with some good default value.

>
> For instance:
>
> class House
> {
>  public:
>    House( DB_Connection & db_connection );
>    House( );
>
>  private:
>    DB_Connection & m_db_connection;
> }
>
> House::House( DB_Connection & db_connection ) : m_db_connection
> ( db_connection )
> {
> }
>
> House::House(  )
> {
> }
>
> This second constructor will not compile since the m_db_connection
> data member is not being initialized.
>
> I suppose I could solve this by making m_db_connection a pointer and
> then having the default constructor initialize the pointer to NULL -
> but now it seems like I'm making changes to my production code simply
> for the sake of making the mock easier to build.

There's nothing wrong with changing your production code simply for
the sake of making it more testable. Testability should be treated as
a first-class citizen.

>
> Thoughts?
>
> Thanks!
> -Michael
>

--
Zhanyong

Michael Jeung

unread,
Jun 5, 2009, 1:08:28 PM6/5/09
to Zhanyong Wan (λx.x x), Google C++ Mocking Framework
> There's nothing wrong with changing your production code simply for
> the sake of making it more testable.  Testability should be treated as
> a first-class citizen.

Ah-ha. I'll give it a shot. Thanks for the response!

-Michael

Reply all
Reply to author
Forward
0 new messages