C++ 给出编译错误的模拟非虚拟方法
我需要编写gtest来测试一些具有非虚拟方法的现有代码,因此我使用下面的源代码进行测试,但是我得到了编译错误 package/web/webscr/sample_template_class3.cpp:在函数int main()中 package/web/webscr/sample_template_class3.cpp:64:error:class-Templatemyclass没有名为-gmock\u display的成员 示例\u模板\u class3.cppC++ 给出编译错误的模拟非虚拟方法,c++,googletest,googlemock,C++,Googletest,Googlemock,我需要编写gtest来测试一些具有非虚拟方法的现有代码,因此我使用下面的源代码进行测试,但是我得到了编译错误 package/web/webscr/sample_template_class3.cpp:在函数int main()中 package/web/webscr/sample_template_class3.cpp:64:error:class-Templatemyclass没有名为-gmock\u display的成员 示例\u模板\u class3.cpp #include <i
#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;
}
#包括
#包括
#包括
使用名称空间std;
模板
类Templatemyclass
{
私人:
MYT类;
公众:
无效显示()
{
T.显示();
}
};
课堂测试
{
公众:
无效显示()
{
cout您的代码中有几个问题。我在下面对其进行了更改,并通过解释的方式对代码进行了注释。如果这不够清楚,请添加注释,我将尝试进一步解释
#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;
}
#包括
#包括
#包括
使用名称空间std;
模板
类Templatemyclass{
私人:
//保留指向“myclass”的非常量引用或指针,以便
//在c'tor中传递的对象在“display()”中使用
//相反,模拟预期将无法满足。
myclass*T;
公众:
//通过非常量引用或指针在命令中传递“myclass”。
显式Templatemyclass(myclass*t):t(t){}
void display(){T->display();}
};
课堂测试{
公众:
void display(){cout如果不想更改源代码,可以利用。
目前它只支持x86 Windows。但Linux和x64 Windows支持很快就会到来。下面的示例将为您提供一个简单的想法:
模拟非虚拟方法
下面的示例使用fakeFunc()
伪造BaseClassTest::getAnInteger()
:
模拟虚拟方法
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;
}
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);
}
模拟静态方法
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;
}
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);
}
弗雷泽的另一个很棒的答案!!!嘿,弗雷泽,我正在四处寻找关于如何在不使用模板的情况下模拟非虚拟方法的信息。我在那里找到了一些非常有趣的答案,包括这两个:和。想听听你的想法!!!我想我倾向于尝试HippoMocks,但我在这里没有个人经验。我们在代码库中使用GoogleMock有一段时间了,设置和维护测试非常痛苦。例如,使用C++11智能指针真的不太好。我听说的另一种可能性是,这应该可以避免您也必须为测试更改生产代码,但我认为它不是免费的在中,我没有个人经验。除此之外,我会选择中提到的两个选项中的一个。我讨厌修改源代码以适应测试,所以我会避免问题中的选项。这样就剩下1.重新声明要测试的函数或2.注入“虚拟”如果设置了一个给定的PP标志。对我来说,决定取决于要测试的实际代码。我倾向于1,因为它是非侵入性的,但如果有很多函数要测试,可能就不可能了。对于2,我会确保PP标志只为那些真正需要它的测试设置-正常测试使用真实的函数。