私は2つのメソッドを持つクラスを持っています
class A
{
void Fun()
{
if(FunRet()>0){///} else {///}
}
int FunRet()
{ return 4;}
};
FunRet が返すものに応じて Fun() メソッドをテストしたい。だから私は FunRet をモックしたいです。私は FunRet を仮想にしたくありません。どうすればそれができますか?
私は2つのメソッドを持つクラスを持っています
class A
{
void Fun()
{
if(FunRet()>0){///} else {///}
}
int FunRet()
{ return 4;}
};
FunRet が返すものに応じて Fun() メソッドをテストしたい。だから私は FunRet をモックしたいです。私は FunRet を仮想にしたくありません。どうすればそれができますか?
クラス内の依存関係を注入できます。この場合、Fun が値を計算する代わりに受け入れるようにします。
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.
};
Fun メソッドを、インターフェイスを実装する電卓クラスに抽出できます。そのインターフェースのインスタンスをコンストラクターでクラス 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
。
this ポインターが欠落していると思います。
... if ( this->FunRet() > 0 ) { ...