Question

I have a mock object setup that looks like this:

MyObject obj;
EXPECT_CALL(obj, myFunction(_))
.WillOnce(Return(1))
.WillOnce(Return(1))
.WillOnce(Return(1))
.WillRepeatedly(Return(-1));

Is there a way to not have to repeat .WillOnce(Return(1)) three times?

Was it helpful?

Solution

using testing::InSequence;

MyObject obj;

{
  InSequence s;
  EXPECT_CALL(obj, myFunction(_))
      .Times(3)
      .WillRepeatedly(Return(1));
  EXPECT_CALL(obj, myFunction(_))
      .WillRepeatedly(Return(-1));
}

OTHER TIPS

For completeness' sake, there's another standard/simple option, though the accepted answer seems clearer in this case.

EXPECT_CALL(obj, myFunction(_)).WillRepeatedly(Return(-1));
EXPECT_CALL(obj, myFunction(_)).Times(3).WillRepeatedly(Return(1)).RetiresOnSaturation();

This can be useful if you know what you want your last/default response to be (-1), but want to muck with the number of times its called before then.

I'm afraid there's no other way to configure this behavior. Can't find an obvious way in the documentation at least.

You'll might get off this problem introducing an appropriate user defined matcher though, that keeps track of a calling count and threshold you can provide from your testcases via template parameters (don't actually know how to induce the ResultType automatically :-( ):

using ::testing::MakeMatcher;
using ::testing::Matcher;
using ::testing::MatcherInterface;
using ::testing::MatchResultListener;

template
    < unsigned int CallThreshold
    , typename ResultType
    , ResultType LowerRetValue
    , ResultType HigherRetValue
    >
class MyCountingReturnMatcher 
: public MatcherInterface<ResultType>
{
public:
    MyCountingReturnMatcher()
    : callCount(0)
    {
    }

    virtual bool MatchAndExplain
        ( ResultType n
        , MatchResultListener* listener
        ) const 
    {
        ++callCount;
        if(callCount <= CallThreshold)
        {
            return n == LowerRetValue;
        }

        return n == HigherRetValue;
    }

    virtual void DescribeTo(::std::ostream* os) const 
    {
        if(callCount <= CallThreshold)
        {
            *os << "returned " << LowerRetValue;
        }
        else
        {
            *os << "returned " << HigherRetValue;
        }
    }

    virtual void DescribeNegationTo(::std::ostream* os) const 
    {
        *os << " didn't return expected value ";
        if(callCount <= CallThreshold)
        {
            *os << "didn't return expected " << LowerRetValue 
                << " at call #" << callCount;
        }
        else
        {
            *os << "didn't return expected " << HigherRetValue 
                << " at call #" << callCount;
        }
    }

private:
    unsigned int callCount;
};

template
    < unsigned int CallThreshold
    , typename ResultType
    , ResultType LowerRetValue
    , ResultType HigherRetValue
    >
inline Matcher<ResultType> MyCountingReturnMatcher() 
{
    return MakeMatcher
               ( new MyCountingReturnMatcher
                    < ResultType
                    , CallThreshold 
                    , ResultType
                    , LowerRetValue
                    , HigherRetValue
                    >()
               );
}

Use then to expect a certainly counted call result:

EXPECT_CALL(blah,method)
   .WillRepeatedly(MyCountingReturnMatcher<1000,int,1,-1>()) // Checks that method
                                                             // returns 1000 times 1
                                                             // but -1 on subsequent 
                                                             // calls.

NOTE
I didn't check this code to be working as intended, but it should guide you into the right direction.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top