Ложный не виртуальный метод, выдающий ошибку компиляции

Мне нужно написать gtest для тестирования некоторого существующего кода, который имеет не виртуальный метод, поэтому я тестирую с использованием приведенного ниже источника, но я получаю ошибку компиляции

package / web / webscr / sample_template_class3.cpp: в функции — main () -:
package / web / webscr / sample_template_class3.cpp: 64: ошибка: у класса Templatemyclassâ нет члена с именем âgmock_displayâ

sample_template_class3.cpp

#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

using namespace std;

template < class myclass>
class Templatemyclass
{
private:
myclass T;
public :

void display()
{
T.display();
}

};

class Test
{
public:
void display()
{
cout<<"Inside the display Test:" <<endl;
}

};

class MockTest

{
public:
MOCK_METHOD0(display,void());
};

class FinalTest
{
public:
void show( Templatemyclass<Test> t)
{
t.display();
cout<<"Inside the display FinalTest:" <<endl;
}};
int main()
{FinalTest test1;
Templatemyclass<Test> obj1;
Templatemyclass<MockTest> obj2;
EXPECT_CALL(obj2,display()).Times(1);
test1.show(obj1);

return 1;
}

2

Решение

В вашем коде есть несколько проблем. Я изменил его ниже и прокомментировал код для пояснения. Если это не достаточно ясно, добавьте комментарий, и я постараюсь объяснить дальше.

#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

using namespace std;

template <class myclass>
class Templatemyclass {
private:
// Hold a non-const ref or pointer to 'myclass' so that the actual
// object passed in the c'tor is used in 'display()'.  If a copy is
// used instead, the mock expectations will not be met.
myclass* T;
public :
// Pass 'myclass' in the c'tor by non-const ref or pointer.
explicit Templatemyclass(myclass* t) : T(t) {}
void display() { T->display(); }
};

class Test {
public:
void display() { cout << "Inside the display Test:" << endl; }
};

class MockTest {
public:
MOCK_METHOD0(display, void());
};

class FinalTest {
public:
// Templatise this function so we can pass either a Templatemyclass<Test>
// or a Templatemyclass<MockTest>.  Pass using non-const ref or pointer
// again so that the actual instance with the mock expectations set on it
// will be used, and not a copy of that object.
template<class T>
void show(T& t) {
t.display();
cout<<"Inside the display FinalTest:" <<endl;
}
};

int main() {
Test test;
Templatemyclass<Test> obj1(&test);

MockTest mock_test;
Templatemyclass<MockTest> obj2(&mock_test);
EXPECT_CALL(mock_test,display()).Times(1);

FinalTest test1;
test1.show(obj1);
test1.show(obj2);

return 0;
}

Следующее могло бы упростить случай:

#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

template <class myclass>
class Templatemyclass {
public:
myclass T;
void show() const { T.display(); }
};

struct Test {
void display() const { std::cout << "Inside the display Test:\n"; }
};

struct MockTest {
MOCK_CONST_METHOD0(display, void());
};

int main() {
Templatemyclass<Test> obj1;
obj1.show();

Templatemyclass<MockTest> obj2;
EXPECT_CALL(obj2.T, display()).Times(1);
obj2.show();

return 0;
}
3

Другие решения

Если вы не хотите менять свой исходный код, вы можете использовать инжектор ++.
В настоящее время он поддерживает только x86 Windows. Но поддержка Linux и x64 Windows скоро появится. Приведенные ниже примеры дадут вам краткое представление:

Ложные не виртуальные методы

Ниже пример подделок BaseClassTest::getAnInteger() используя fakeFunc():

class FakeClassNonVirtualMethodTestFixture : public ::testing::Test
{
public:
int fakeFunc()
{
return 6;
}
};

TEST_F(FakeClassNonVirtualMethodTestFixture, FakeIntFunctionWhenCalled)
{
// Prepare
int expected = 6;
InjectorPP::Injector injector;

injector.whenCalled(INJECTORPP_MEMBER_FUNCTION(BaseClassTest::getAnInteger))
.willExecute(INJECTORPP_MEMBER_FUNCTION(FakeClassNonVirtualMethodTestFixture::fakeFunc));

BaseClassTest b = BaseClassTest();

// Act
// FakeFunc will be executed!
int actual = b.getAnInteger();

// Assert
EXPECT_EQ(expected, actual);
}

Поддельные виртуальные методы

Injector ++ поддерживает виртуальные методы насмешек (Удивительно, да?). Ниже приведен простой пример:

int FakeIntFuncForDerived()
{
return 2;
}

TEST_F(FakeClassVirtualMethodTestFixture, MockDerivedClassVirtualMemberFunctionWhenCalled)
{
// Prepare
int expected = 2;
BaseClassTest* derived = new SubClassTest();

InjectorPP::Injector injector;
injector.whenCalledVirtualMethod(derived, "getAnIntegerVirtual")
.willExecute(fakeIntFuncForDerived);

// Act
// FakeIntFuncForDerived() will be exectued!
int actual = derived->getAnIntegerVirtual();

// Assert
EXPECT_EQ(expected, actual);

delete derived;
derived = NULL;
}

Ложные статические методы

Injector ++ поддерживает статический метод пересмешивания. Ниже приведен простой пример:

Address FakeGetAnAddress()
{
Address addr;
addr.setAddressLine("fakeAddressLine");
addr.setZipCode("fakeZipCode");

return addr;
}

TEST_F(FakeClassNonVirtualMethodTestFixture, FakeStaticFunctionReturnUserDefinedClassWhenCalled)
{
// Prepare
Address expected;
expected.setAddressLine("fakeAddressLine");
expected.setZipCode("fakeZipCode");

InjectorPP::Injector injector;

injector.whenCalled(INJECTORPP_STATIC_MEMBER_FUNCTION(BaseClassTest::getAnAddressStatic))
.willExecute(INJECTORPP_MEMBER_FUNCTION(FakeClassNonVirtualMethodTestFixture::fakeGetAnAddress));

// Act
// FakeGetAnAddress will be executed!
Address actual = BaseClassTest::getAnAddressStatic();

// Assert
EXPECT_EQ(expected, actual);
}
0

По вопросам рекламы [email protected]