我有2種方法方法和模擬用同一類
class A
{
void Fun()
{
if(FunRet()>0){///} else {///}
}
int FunRet()
{ return 4;}
};
我想測試玩轉()方法取決於什麼FunRet收益類。所以我想嘲笑FunRet。 我寧願不想讓FunRet變得虛擬。我該怎麼做?
我有2種方法方法和模擬用同一類
class A
{
void Fun()
{
if(FunRet()>0){///} else {///}
}
int FunRet()
{ return 4;}
};
我想測試玩轉()方法取決於什麼FunRet收益類。所以我想嘲笑FunRet。 我寧願不想讓FunRet變得虛擬。我該怎麼做?
我想你錯過了這個指針。
... if (this->FunRet() > 0) { ...
你可以注入類內的依賴。在這種情況下,使樂趣接受一個值,而不是計算它:
class A
{
void Fun(int x)
{
if(x>0){///} else {///}
}
int FunRet()
{ return 4;}
};
然後您的測試可以將任意值傳遞到Fun()。如果您需要強制執行正確的使用,寫一個公共版本的API和一個私人版本,露出來進行測試:
class A {
public:
void Fun() { return Fun(FunRet()); }
private:
void Fun(int x); // for testing.
};
您可以提取玩轉方法爲實現接口計算器類。您應該在構造函數中將該接口的實例傳遞給類A.
在測試中,您可以讓其他類實現該接口,並返回其他值。
這種方法也具有很大的優勢,您可以分別計算一個值和使用計算的值。
class A {
public:
A (IFunCalc calc) { m_calc = calc; }
void Fun { if calc.FunRet() > 4 ... }
private:
IFunCalc m_calc;
}
class FunCalc : IFunCulc {
public:
int FunRet { return 4; }
}
class FunCalc4Test : IFunCalc {
public:
int FunRet { return 27; }
}
如果你使用依賴注入和模板測試你的對象,你可以使用模擬對象而不必使用虛函數。
class AParameters
{
public:
int FunRet()
{ return 4;}
};
class MockAParameters
{
public:
MOCK_METHOD0(FunRet, int());
};
template<class Parameters>
class AImpl
{
public:
AImpl(Parameters& parameters):parameters(parameters){}
void Fun()
{
if(parameters.FunRet()>0){///} else {///}
}
private:
Parameters& parameters;
};
typedef AImpl<AParameters> A;
typedef AImpl<MockAParameters> ATestObject;
void Test::funUsesFunRet()
{
MockAParameters params;
EXPECT_CALL(params, FunRet());
ATestObject object(params);
object.Fun();
}
我相信FunRet
是Fun
內部實現細節。因此,Fun
不需要與FunRet
隔離進行測試。只需測試Fun
,不要擔心它調用FunRet
的事實。