1

In the googletest Primer, there is an example, where the SetUp/TearDown are virtual. Can someone explain why they are virtual? Here is an example verbatim from the primer:

class QueueTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    q1_.Enqueue(1);
    q2_.Enqueue(2);
    q2_.Enqueue(3);
  }

  // virtual void TearDown() {}

  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

TEST_F(QueueTest, IsEmptyInitially) {
  EXPECT_EQ(0, q0_.size());
}

I wonder why not writing it as follows. Will the behavior change?

class QueueTest : public ::testing::Test {
 protected:
  void SetUp() override {
    q1_.Enqueue(1);
    q2_.Enqueue(2);
    q2_.Enqueue(3);
  }

  // void TearDown() override {}

  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

TEST_F(QueueTest, IsEmptyInitially) {
  EXPECT_EQ(0, q0_.size());
}
RafazZ
  • 4,049
  • 2
  • 20
  • 39
  • 2
    If a member function have been marked as `virtual` in a base-class, then it's not needed in the child-classes. – Some programmer dude Aug 22 '17 at 02:52
  • @Someprogrammerdude Yes, I understand that part. My question is, why is the documentation showing the `virtual` in the child class, calls the test, and exits? It doesn't make sense to me, as nothing is expected to inherit from the `QueueTest` in the example above – RafazZ Aug 22 '17 at 02:54
  • Maybe a force of habit? It used to be so in just about all text-books once, and almost everybody did it. What you have in the second example, especially with the C++11 keyword `override` is IMO better. – Some programmer dude Aug 22 '17 at 03:48
  • I am not sure -- I found a long discussion thread on the `googlemock` git website discussing `override` keyword, but the issue is still open. – RafazZ Aug 22 '17 at 04:13
  • I think googletest predates C++11 (thus `override` keyword) and nobody bothered to update documentation since then, – el.pescado - нет войне Aug 22 '17 at 05:47
  • Whats the question? Is it "why overridden functions are marked with `virtual`" or is it "why those functions were marked as `virtual` in `testing::Test`"? – el.pescado - нет войне Aug 22 '17 at 08:23

2 Answers2

3

Given than both SetUp and TearDown are declared virtual in parent class, all three declaration in subclasses are equivalent:

virtual void SetUp() {}
void SetUp() {}
void SetUp() override {}

I'd stick to using override, as any typo (like void setUp() override) would cause compilation error.

As override keyword was only introduced in C++11 and google test framework was created before it was available, I assume that override is not used in documentation because simply no one bothered to update it.

0

In the googletest Primer, there is an example, where the SetUp/TearDown are virtual. Can someone explain why they are virtual? Here is an example verbatim from the primer:

class QueueTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    q1_.Enqueue(1);
    q2_.Enqueue(2);
    q2_.Enqueue(3);
  }

  // virtual void TearDown() {}

  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

TEST_F(QueueTest, IsEmptyInitially) {
  EXPECT_EQ(0, q0_.size());
}
I wonder why not writing it as follows. Will the behavior change?

class QueueTest : public ::testing::Test {
 protected:
  void SetUp() override {
    q1_.Enqueue(1);
    q2_.Enqueue(2);
    q2_.Enqueue(3);
  }

  // void TearDown() override {}

Making the member functions virtual and protected implies that there is scope to override the members in case one needs to (customization), but also that there is some required implementation in the base members. If one does choose to override, one should call the base methods. The virtual keyword in base class Test indicates that there is scope for polymorphic extension.

I would override as follows (only if I have additional behavior to add):

...
void TearDown() override
{
  //Call base TearDown - important
  Test::TearDown();
  //... My code
}
...

Alternatively (when not needing to override), one can either do nothing, or use...

using testing::TearDown; 

... to make it clear to users of your class that TearDown is part of the interface

Werner Erasmus
  • 3,988
  • 17
  • 31