5

我有 2 种方法的课程

class A
{
  void Fun()
  {
    if(FunRet()>0){///} else {///}
  } 
  int FunRet()
  { return 4;}
};

我想测试 Fun() 方法取决于 FunRet 返回的内容。所以我想模拟 FunRet。我宁愿不想让 FunRet 成为虚拟的。我怎么能这样做?

4

5 回答 5

3

您可以注入类内依赖项。在这种情况下,让 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.
};
于 2011-06-08T15:13:28.907 回答
1

您可以将 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; }
}
于 2011-06-14T11:46:28.913 回答
0

我认为您缺少 this 指针。

... if ( this->FunRet() > 0 ) { ...

于 2011-06-08T12:46:38.053 回答
0

如果您使用依赖注入并模板化您的被测对象,您可以使用模拟对象而无需使用虚函数。

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();
}
于 2011-06-14T23:27:06.693 回答
0

我相信FunRetFun. 因此,Fun不需要与FunRet. 只需测试Fun,不要担心它调用的事实FunRet

于 2014-01-11T00:54:39.190 回答