RudeMocks/Out and In-Out Arguments

From Wiki

Jump to: navigation, search

Contents

Table of Contents

Introduction

Given a function signature like this

void FunctionWithOutArguments(int& refValue, float* ptrValue);

refValue and ptrValue can be out or in-out parameters. RudeMocks supports specifying return values for these types of parameters directly by using OutArg(index) and InOutArg(index) instead of Arg(index) to access the argument options for a specific argument. OutArg() and InOutArg() support all the same options as Arg() does. But additionally, they support Return() to specify a return value.

Out Arguments

Assuming both arguments of the above function are out parameters, setting up an expectation that returns specific values during replay mode is done like this:

int i = 0;
float f = 1.0f;
FunctionWithOutArguments(i, &f);
LastCall().OutArg(0).Return(5).OutArg(1).Return(7.0f);

Note that for out parameters RudeMocks by default does not perform any actual argument verification. In particular, OutArg() automatically calls the Ignore() argument option on the argument so that any values passed in for it during replay are ignored.

mocks.Replay();
 
// Note that the argument values are not verified for out parameters.
// So in this example, i2 and f2 could have any value. As long as we
// call the function, verification will succeed.
int i2 = 7;
float f2 = 2.0f;
FunctionWithOutArguments(i2, &f2);
 
// Check that the mocked function returned what we set up while recording expectations.
assert(5 == i2);
assert(7.0f == f2);
 
mocks.Verify();

In-Out Arguments

Now let's assume that the two parameters of FunctionWithOutArguments are actually in-out parameters, i.e. we want to verify the actual argument values passed to the function and return mock values during replay. The InOutArg() option is used for exactly this purpose:

int i = 0;
float f = 1.0f;
FunctionWithOutArguments(i, &f);
LastCall().InOutArg(0).Return(5).InOutArg(1).Return(7.0f);

Unlike OutArg(), InOutArg() does not call Ignore() on the argument. Therefore, actual argument values will be verified and compared against the values recorded during replay. Note that RudeMocks does _not_ store copies of the passed in values. Instead, a reference to the i variable and a pointer to the f variable are stored directly. Therefore, these two variables must not go out of scope until the end of the test!

mocks.Replay();
 
// Argument values are verified for in-out parameters. So make
// sure the correct values are passed in.
int i2 = 0;
float f2 = 1.0f;
FunctionWithOutArguments(i2, &f2);
 
// Check that the mocked function returned what we set up while recording expectations.
assert(5 == i2);
assert(7.0f == f2);
 
mocks.Verify();

Using Do() to Compute Out Values

Instead of using OutArg() or InOutArg() you can also use the Do() argument option to specify not only custom argument verification but also custom return values for out parameters. This works by calling the SetOutValue() function on the passed-in ArgumentValue objects. Note that this function is only available for out parameters, i.e. non-const types of the form T& and T*. Here's an example based on the above function:

bool CustomVerifyIntRef(std::size_t argumentIndex, ArgumentValue<int&> expectedValue, ArgumentValue<int&> actualValue, std::string& description)
{
    // This is an in-out parameter that compares for equality and returns two times the passed in actual value.
    bool succeeded = expectedValue.GetValue() == actualValue.GetValue();
    actualValue.SetOutValue(actualValue.GetValue() * 2);
    return succeeded;
}
 
bool CustomVerifyFloatPtr(std::size_t argumentIndex, ArgumentValue<float*> expectedValue, ArgumentValue<float*> actualValue, std::string& description)
{
    // This is an out parameter that ignores the expected value and returns a predefined out value.
    actualValue.SetOutValue(50.0f);
    return true;
}
 
int i = 100;
float f = 1.0f;
FunctionWithOutArguments(i, &f);
 
CustomArgumentVerifier<int&>::Function customArg0Function(&CustomVerifyIntRef);
CustomArgumentVerifier<float*>::Function customArg1Function(&CustomVerifyFloatPtr);
LastCall().Arg(0).Do(customArg0Function).Arg(1).Do(customArg1Function);
 
mocks.Replay();
 
i = 100;      // This value should get multiplied by two by the function.
f = 2.0f;     // This value is ignored. It will be set to a predefined value.
FunctionWithOutArguments(i, &f);
 
assert(200 == i);
assert(50.0f == f);
 
mocks.Verify();
Personal tools