[英]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.