I tried to count the number of test classes, like this:
int classCount = 0;
class TestClass2 : public testing::Test {
protected:
static void SetUpTestCase() {
}
static void TearDownTestCase() {
}
virtual void SetUp() { classCount++; }
virtual void TearDown() {}
};
TEST(TestClass1, classCount) {
cout << typeid(*this).name() << endl;
EXPECT_EQ(1, classCount);
}
Unfortunately, the classCount is 0. I was expecting that when TestClass1_xxxx class is initialized, the classCount will +1 by virtual void SetUp() { classCount++; }. But actually it's not called. I added cout inside virtual void SetUp() { classCount++; } but still saw not console output.
So my question is, when is virtual void SetUp() {} begin called? Is it called automatically in some way?
You can remove the whole class and the code will still compile.
int classCount = 0;
TEST(TestClass1, classCount) {
cout << typeid(*this).name() << endl;
EXPECT_EQ(1, classCount);
}
Because class TestClass2 is a test fixture class and should be used with the macro TEST_F.
int classCount = 0;
class TestClass2 : public testing::Test {
protected:
static void SetUpTestCase() {
}
static void TearDownTestCase() {
}
void SetUp() override { classCount++; }
void TearDown() override {}
};
// ▼▼
TEST_F(TestClass1, classCount) {
cout << typeid(*this).name() << endl;
EXPECT_EQ(1, classCount);
}
What is you real problem? That code smells XY problem.
Related
Consider the next Example:
#include <iostream>
class Base{
public:
virtual void f() {
std::cout << "Base::f()" << std::endl;
}
};
class Derived1 : public Base
{
public:
virtual void f() override
{
Base::f();
std::cout << "Derived1::f()" << std::endl;
}
};
class Derived2 : public Base
{
public:
virtual void f() override
{
Base::f();
std::cout << "Derived2::f()" << std::endl;
}
};
class DerivedUnion : public Derived1, public Derived2
{
public:
void Derived1::f() override { // Errors
}
void Derived2::f() override { // Errors
}
};
is there some how that allow me to override the
Derived2::f()
in the
DerivedUnion{}
class?
I have tried to target specific one with namespace like style, but it didnt worked:
class DerivedUnion : public Derived1, public Derived2
// Notice DerivedUnion is not a Union, name is for
// Demostration Purposes, not intended to create
// A union Behavior
{
public:
virtual void Derived1::f() override; // Compile error
virtual void Derived2::f() override; // Compile error
virtual void f() override; // Not a compile error, but both Derived1 and Derived2 call same
};
void UseBase(Base* b){
b->f(); // expected Ambiguos call compile time
b->DerivedUnion::f() // Expected overriden DerivedUnion::f() to be called
b->Derived1::f(); // Expected overriden Derived1::f() to be called
b->Derived2::f(); // Expected overriden Derived2::f() to be called
}
An Example of it could be this one, code is self explanatory:
#include <iostream>
/* Interface Drawable */
class IDrawable {
public:
virtual void Draw() {};
};
/* Asume this is a button from one kind of bar */
class ButtonA : public IDrawable{
public:
virtual void Draw() override {
std::cout << "ButtonA::Draw()" << std::endl;
}
};
/* Asume this is a button from another kind of bar */
class ButtonB : public IDrawable{
public:
virtual void Draw() override {
std::cout << "ButtonB::Draw()" << std::endl;
}
};
/**
Where Component X is a representation that will represent 2 buttons types
*/
class ComponentX : public ButtonA, public ButtonB {
public:
void ButtonA::Draw() override { // cannot define member function ‘ButtonA::Draw’ within ‘ComponentX’
ButtonA::Draw();
std::cout << "Custom ComponentX::Draw()" << std::endl;
}
void ButtonB::Draw() override { // error: cannot define member function ‘ButtonB::Draw’ within ‘ComponentX’
ButtonB::Draw();
std::cout << "Custom ComponentX::Draw()" << std::endl;
}
};
class ComponentY : public ButtonA, public ButtonB {
public:
void ButtonA::Draw() override { // cannot define member function ‘ButtonA::Draw’ within ‘ComponentY’
ButtonA::Draw();
std::cout << "Custom ComponentY::Draw()" << std::endl;
}
void ButtonB::Draw() override { // error: cannot define member function ‘ButtonB::Draw’ within ‘ComponentY’
ButtonB::Draw();
std::cout << "Custom ComponentY::Draw()" << std::endl;
}
};
using namespace std;
void DummyAddButtonA(ButtonA* pBtnA)
{
//Add it somewhere ...
}
void DummyAddButtonB(ButtonB* pBtnB)
{
//Add it somewhere ...
}
int main()
{
ComponentX compx;
ComponentY compy;
DummyAddButtonA(&compx);
DummyAddButtonB(&compx);
DummyAddButtonA(&compy);
DummyAddButtonB(&compy);
return 0;
}
I want to implement a simple test structure. Here is how I created base class and derived class.
testBase.h:
class TestBase {
public:
TestBase() {}
virtual void TestStart() = 0;
virtual void TestEnd() = 0;
void RunTest() {
// I need code here to trigger a chain of calls
}
};
classifierTest.h:
#include "testBase.h"
class ClassifierTest: public TestBase
{
public:
ClassifierTest() {
}
void TestStart();
void TestEnd();
void Test1();
void Test2();
void Test3();
};
classifierTest.cpp:
#include "classifierTest.h"
void ClassifierTest::TestStart() {
}
void ClassifierTest::TestEnd() {
}
void ClassifierTest::Test1(){
}
void ClassifierTest::Test2(){
}
void ClassifierTest::Test3(){
}
main function:
ClassifierTest *classifierTest = new ClassifierTest();
classifierTest->RunTest();
Suppose Test1(), Test2() and Test3() are my test methods, and I may add more tests here in future.
My goal is that when I call RunTest() in the main function, then these test methods are called one by one, after TestStart(), and before TestEnd().
so they would run like:
TestStart()
Test1()
TestEnd()
TestStart()
Test2()
TestEnd()
TestStart()
Test3()
TestEnd()
I don't want to specifically add test method in the base class. But the question is how to trigger these chain of calls from RunTest(). So the base trigger methods that it doesn't know about them.
I believe it should be sth like reflection in .net?
You are basically asking for reflection which isnt present in C++ (yet). Now the quesiton is what comprosmise you are willing to make.
If you are fine with writing some code to manually register the test functions, then they don't need to be members and a possible solution is this:
#include <functional>
#include <vector>
#include <iostream>
class TestBase {
public:
TestBase() {}
virtual void TestStart() = 0;
virtual void TestEnd() = 0;
void RunTest() {
for (const auto& test_fun : test_functions){
TestStart();
test_fun();
TestEnd();
}
}
using test_function = std::function<void()>;
void register_test(const test_function& fun){ test_functions.push_back(fun); }
private:
std::vector<test_function> test_functions;
};
class ClassifierTest: public TestBase
{
public:
ClassifierTest() {
register_test([](){ std::cout << "test 1\n";});
register_test([](){ std::cout << "test 2\n";});
}
void TestStart() { std::cout << "test start\n";}
void TestEnd() { std::cout << "test end\n";}
};
int main() {
ClassifierTest{}.RunTest();
}
Output:
test start
test 1
test end
test start
test 2
test end
Note that if you capture this the lambdas can use members, so there isnt much difference to your initial approach and the amount of code to write is also comparable:
class ClassifierTest2: public TestBase
{
public:
ClassifierTest2() {
register_test([this](){ std::cout << "test 1, x = " << x << "\n";});
register_test([this](){ std::cout << "test 2, x = " << x << "\n";});
}
void TestStart() { ++x;std::cout << "test start\n";}
void TestEnd() { std::cout << "test end\n";}
private:
int x = 0;
};
int main() {
ClassifierTest2{}.RunTest();
}
Output:
test start
test 1, x = 1
test end
test start
test 2, x = 2
test end
As mentioned already in a comment, if you manually register TestStart and TestEnd as well, then there is no need for the derived classes. It could be just a class Test with register_test_start(std::function<void()>) and register_test_end(std::function<void()>) or pass them as parameters to the constructor.
I am having a hard time trying to compile the following code using clang compiler. I am not sure if I am using enable_shared_from_this and shared_From_this() in the right way, or breaking rule inadvertently. Can someone point me out what is exactly causing problem.
#include <iostream>
#include <memory>
class IB {
public:
virtual void Calle() =0;
virtual void Show() = 0;
};
class IC {
public:
virtual void Calle() =0;
virtual void Print() =0;
};
class CB;
class CC;
class CA : public std::enable_shared_from_this<CA> {
private:
std::shared_ptr<IB> m_ib;
public:
CA()
: m_ib(std::make_shared<CB>(shared_from_this())) {
std::cout << "Created CA obj\n";
}
void Calle() {
if(m_ib) m_ib->Calle();
// Show();
}
void Show() {
std::cout << "Printing from here. CA\n";
}
};
class CB : public IB, public std::enable_shared_from_this<CA> {
private:
std::shared_ptr<IC> m_ic;
std::shared_ptr<CA> m_ca;
public:
CB() : CB(nullptr){}
CB(const std::shared_ptr<CA> a)
: m_ca(a)
, m_ic(std::make_shared<CC>(shared_from_this())) {
std::cout << "Created CB obj\n";
}
virtual void Calle() override;
virtual void Show() override;
};
void CB::Calle() {
if(m_ca) m_ca->Show();
if(m_ic) m_ic->Print();
Show();
}
void CB::Show() {
std::cout << "Printing from here. CB\n";
}
class CC : public IC, public std::enable_shared_from_this<CA> {
private:
std::shared_ptr<IB> m_ib;
public:
CC()
: CC(nullptr){}
CC(const std::shared_ptr<CB> b)
: m_ib(b){
std::cout << "Created CC obj\n";
}
virtual void Calle() override;
virtual void Print() override;
};
void CC::Calle() {
if(m_ib) m_ib->Show();
}
void CC::Print() {
std::cout << "Printing from here. CC\n";
}
int main() {
auto a = std::make_shared<CA>();
a->Calle();
return 0;
}
With the reference of this Stackoverflow question, I'm not able to figure out the same problem of implementing DI using interface in c++ style, i.e. abstract class. Instead of bumping up old thread I created this one. Compiler throws error for the last line.
class IService {
virtual void DoWork() = 0;
virtual bool IsRunning() = 0;
};
class ClientA : IService {
void DoWork() {
std::cout << "Work in progress inside A";
}
bool IsRunning() {
return true;
}
};
class ClientB : IService {
void DoWork() {
std::cout << "Work in progress inside B";
}
bool IsRunning() {
return true;
}
};
class Server {
IService* _service;
Server(IService* service) : _service(service)
{ }
// Error: this declaration has no storage class or type specifier
// Compiler: MSVC 2017
_service->DoWork();
};
In C++ class members are private by default.
You should specify public: before virtual void DoWork() = 0;.
C++ inheritance is private by default (when using class keyword). Instead of : IService, try : public IService. See differences between private, protected, public inheritance here.
Where is the function body of _service->DoWork();?
I believe this is what you wanted:
#include <iostream>
using namespace std;
struct IService {
virtual ~IService() = default; // Remember about virtual dtor to avoid memory leaks!
virtual void DoWork() = 0;
virtual bool IsRunning() = 0;
};
class ClientA : public IService {
void DoWork() {
std::cout << "Work in progress inside A" << endl;
}
bool IsRunning() {
return true;
}
};
class ClientB : public IService {
void DoWork() {
std::cout << "Work in progress inside B" << endl;
}
bool IsRunning() {
return true;
}
};
class Server {
IService* _service;
public:
Server(IService* service) : _service(service)
{ }
void doStuff() {
_service->DoWork();
}
};
int main() {
ClientA a;
ClientB b;
Server sa(&a), sb(&b);
cout << "ServerA: " << endl;
sa.doStuff();
cout << "ServerB: " << endl;
sb.doStuff();
return 0;
}
Ideone
You need to get yourself familiar with the concept of access specifiers in C++. See here
I was reading about delegation and I wanted to able to call with a base class a any function pass as parameter depending on the event, I did it this way and it works but I am not sure if it is the proper way and if it is portable like this.
class base {
public:
typedef void (base::*methodPTR)();
methodPTR pfn;
void setMethod(methodPTR fn)
{
pfn = fn;
}
void run(){
if(pfn) (this->*pfn)();
}
};
class a : public base {
public:
void fn()
{
cout<<"from class a!"<<endl;
}
};
class b : public base
{
a ob;
public:
void init()
{
ob.setMethod(static_cast<base::methodPTR>(&b::fn));
}
void fn()
{
cout << "from class b!" << endl;
}
void test()
{
ob.run();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
b x;
x.init();
x.test();
return 0;
}
You are calling the member function fn of class b with an instance of class a which will cause undefineded behaviour if you access data memebers of your class.
Replace your classes a and b with this to see the magic :
class a : public base {
int j;
public:
a()
{
j = 42;
}
void fn()
{
cout<<"from class a!"<<endl;
}
};
class b : public base
{
int i;
a ob;
public:
void init()
{
i = 5;
ob.setMethod(static_cast<base::methodPTR>(&b::fn));
}
void fn()
{
cout << "from class b!" << endl;
cout << "i = " << i << endl;
}
void test()
{
ob.run();
}
};