[英]googlemock how to use mocking in test
我是 google mock 的初学者,我不知道如何使用它和这个概念。
如果我试图从 class 中测试一个方法,该方法正在从不同的类中调用一些其他方法。 我是否需要从我的测试方法正在调用的不同类中模拟所有这些方法。 这是一个例子:
class A {
public:
A () {}
int setnum(int num) {//do some stuff return 1 or 0//
}
private:
int _num;
};
class B {
public:
B (){}
int init(A *a, int number){
if(a->setnum(number))
return 1;
return 0;
}
void setNum(int num){_num=num;}
private:
A *_a;
int _num;
};
class C {
public:
int doSoemthing(A *a, int number){
if (domore(a,number))
return 1;
return 0;
}
int domore(A *a, int number){
if(_b.init(a,number))
return 1;
return 0;
;}
private:
B _b;
};
我是否需要模拟测试我的测试方法所需的 class A 和 B 中的所有方法? 或者我可以只模拟一个 Class,然后测试这个 class 是否工作。
In order to test C class with mocks, you need to introduce an interface for the dependency than is to be used in C class (here, added BIface). 然后你需要使用 BIface 的依赖注入到 C class (通过添加的ctor)。 有了它,您将能够测试 B 和 C 类的交互。 IMO A class 不需要在 CTest 中进行模拟(但很可能需要在 BTest 中进行测试)
class A {
public:
A() {} // not needed
int setnum(int num) { // do some stuff return 1 or 0//
}
private:
int _num;
};
class BIface {
public:
virtual ~BIface() = default;
virtual int init(A *a, int number) = 0;
virtual void setNum(int num) = 0;
};
class B : public BIface {
public:
B() {} // not needed
int init(A *a, int number) override {
if (a->setnum(number))
return 1;
return 0;
}
void setNum(int num) override {
_num = num;
}
private:
A *_a;
int _num;
};
class C {
public:
C(BIface &b) : _b{b} {}
int doSoemthing(A *a, int number) {
if (domore(a, number))
return 1;
return 0;
}
int domore(A *a, int number) {
if (_b.init(a, number))
return 1;
return 0;
;
}
private:
BIface &_b;
};
class BIfaceMock : public BIface {
public:
MOCK_METHOD2(init, int(A *, int));
MOCK_METHOD1(setNum, void(int));
};
TEST(CTest, givenDoingMoreWhenInitOfBReturnOneThenReturnOne) {
// can be done in CTest ctor if more tests are needed to avoid code duplciation
BIfaceMock bMock{};
A a{}; // `a` doesn't need to be mocked in CTest. It shall be mocked in BTest as it is dependency of B class, not C class
C testedObject{bMock}; // dependency injection of BFace to C
const auto SOME_INT_PARAM = 42;
// Eq mather is used to match both &a and SOME_INT_PARAM. This confirms proper parameters were passed to init
EXPECT_CALL(bMock, init(&a, SOME_INT_PARAM)).WillOnce(Return(1));
ASSERT_EQ(1, testedObject.domore(&a, SOME_INT_PARAM));
}
我不是 100% 确定,但在您的示例中,您根本不必使用模拟。 您可以在这里非常轻松地创建对象。
当我希望调用某个方法并返回特定值时,我会使用模拟 - 我不是在测试这个方法,而是在测试 if-statment:
A a;
if(a.method())
{
// some logic
}
EXPECT_CALL(aMock.method()).WillOnce(Return(true));
但是您可以在更多情况下使用它(例如:您可以避免创建非常大的 class 并将其替换为模拟对象)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.