Mockk: Mock a global function with overloads - unit-testing

Mockk added support for mocking global functions.
However, when they have overloads there's a problem.
For example if you try to mock delay() with mockkStatic(::delay) you encounter this error:
Overload resolution ambiguity:
public suspend fun delay(timeMillis: Long): Unit defined in kotlinx.coroutines
public suspend fun delay(duration: Duration): Unit defined in kotlinx.coroutines
Is there a way to mock a global function that has overloads?

That one is a bit tricky, because it seems to be impossible to access the declaring class of such a global function using Kotlin reflection. However, it is possible to use Java reflection, if you know at least one other function in the same file that is not overloaded.
Let's for instance assume that you mean delay of coroutines, there is the function awaitCancellation defined in the same file.
We can use that to access the Java class that declares delay and query it for the right implementation of delay:
val declaringClass = ::awaitCancellation.javaMethod!!.declaringClass
val methods = declaringClass.declaredMethods
val ref = methods.mapNotNull { it.kotlinFunction }
.filter { it.name == "delay" }
.first { it.parameters[0].type == Long::class.createType() }
mockkStatic(ref)
In this example, ref points to the implementation of delay that takes a Long as parameter.
For the other implementation we would need to replace Long with Duration in the last condition.

Related

Can you mock C functions with Googlemock without creating a global mock instance?

The generally used approach of wrapping free C functions in a "Mockinterface" class with a child class "Mock"(that calls MOCK_METHOD) results in the need of a global mock variable in order to use it in a TEST.
Is there another design approach that does not need a global Mock object/pointer so we could use a local Mock object in TEST?
It doesn't matter whether the mock object is globally static, locally static, or locally dynamic. You just need to make sure that it exists when the mocked C function is called and wants to call the method of the mock object.
The important part is that the per-se static C functions need to access that mock object. In consequence you need some kind of static variable. It does not need to be the mock object.
I realized this with a class variable (in contrast to a member variable) that stores a pointer to the single mock object. If you are sure that at most one mock object exists at a time, you can even save some effort because of possibly multiple instantiations.
For example:
class FunctionsMock
{
public:
static FunctionsMock* instance;
FunctionsMock()
{
instance = this;
}
~FunctionsMock()
{
instance = nullptr;
}
MOCK_METHOD(int, function1, (int p));
MOCK_METHOD(void, function2, ());
};
An implementation can look like:
FunctionsMock* FunctionsMock::instance = nullptr;
extern "C" int function1(int p)
{
if (FunctionsMock::instance == nullptr)
{
ADD_FAILURE() << "FunctionsMock::instance == nullptr";
return 0; // some sensible value
}
return FunctionsMock::instance->function1(p);
}
extern "C" void function2()
{
ASSERT_NE(FunctionsMock::instance, nullptr);
FunctionsMock::instance->function2();
}
Note: Since you cannot use ASSERT_NE in a function that returns a value, you need to check the condition explicitly and in case call ADD_FAILURE.
Now you can define a local mock object and check that expected functions are called:
TEST(SuiteName, TestName)
{
FunctionsMock mock;
EXPECT_CALL(mock, function1(...
EXPECT_CALL(mock, function2())...
// ...
}
If you want multiple concurrent mock objects, the C functions needs to know which mock object has to be used. I did not dive into this since we did not need it. All our tests run sequentially. You might want to do some research, depending on the kind of multitasking you do.
If you just want to use the latest instance, you can provide a static stack of mock object pointers instead of the single pointer.

Lambda <-> closure equivalence in C++

I was watching a video called Lambda? You Keep Using that Letter by Kevlin Henney, where he states that closures and objects are fundamentaly equivalent:
He then proves his point by this javascript code which implement a stack as a closure:
const newStack = () => {
const items = []
return {
depth: () => items.lengh,
top: () => items[0],
push: newTop => { items.unshift(newTop) },
pop: () => { items.shift() },
}
}
The advantage of a closure versus a class is that its state is really hidden, whereas a private member is more "inaccessible" than "hidden".
I tried to do something equivalent in C++. However, it seems that it is difficult to express this in C++.
My current version is there, and it has two major drawbacks:
it does compile, but it will not work (the inner shared_ptris released immediately after the closure creation)
is a bit verbose : depth, top, push and pop are repeated 3 times.
auto newStack = []() {
auto items = std::make_shared<std::stack<int>>();
auto depth = [&items]() { return items->size();};
auto top = [&items]() { return items->top(); };
auto push = [&items](int newTop) { items->push(newTop); };
auto pop = [&items]() { items->pop(); };
struct R {
decltype(depth) depth;
decltype(top) top;
decltype(push) push;
decltype(pop) pop;
};
return R{ depth, top, push, pop};
};
godbolt version here
Is there a working way to do it in C++?
Yes, of course there's a better way to do it in C++: don't use a lambda.
A lambda expression defines a class. A closure is an instance of that class--an object. We don't need comparisons to other languages to tell us that--it's exactly how lambdas and closures are defined in C++. ยง[expr.prim.lambda.closure]:
The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type, whose properties are described below.
But (and this is an important point) at least in C++, a lambda expression defines a class with a very limited public interface. Specifically, it provides an overload of operator(), and if it doesn't capture anything, a conversion to pointer to function. If it does capture something, it also defines a constructor to do the capturing. And of course if it captures things, it defines member variables to hold whatever it captures.
But that's all it really defines. It's not that it's doing a better job of hiding whatever else it may contain. It's that it really doesn't contain anything else.
In your case, you're trying to define a type that has four separate member functions that all operate on some state they share. As you've shown, it's sort of possible to do that externalizing the state so you have something nearly equivalent to some C code (or something on that order) that simply has data and some functions that operate on that data. And yes, you can push them together into a structure to do at least some imitation of a class with member functions.
But you're pretty much fighting against the system (so to speak) to do that in C++. Lambdas/closures (as they're defined in C++) are not intended to let you define things that have multiple separate entry points, each carrying out separate actions on shared data. As Samuel Johnson's old line says, "[It] is like a dog walking on its hind legs. It is not done well; but you are surprised to find it done at all."

Does passing lambdas violate encapsulation when they use a private member variable?

I wrote a function to pass to a third party's class. A static function worked fine until the function needed access to a private member variable to do its work. I can do that using a lambda expression (given that it is converted to std::function either automatically or by casting).
Example:
void classA::doingThings()
{
...
classB::needsHelpToDoAThing(
[&](std::type foo) -> size_t { return myFunction(foo); }
);
...
}
size_t class::myFunction(type foo){
...
type someVar = m_somePrivateMember ...(some work)
...
}
But I don't really understand what I'm doing. Now this other class is using private member variables from a different class. Doesn't this violate encapsulation? Is this a hack or am I missing/misunderstanding a concept?
Encapsulation is the idea that other code doesn't get to poke around in your innards willy-nilly.
Here you created a helper function that can poke around in your innards. This helper function is part of your innards, even if you pass it to someone else.
This no more breaks encapsulation than a member method accessing private data. While it isn't part of the interface of the class explicitly, it is still part of the implementation.

Syntax clarification

I was browsing some of Ubuntu's Mir examples and i stumbled upon code that i couldn't understand.
struct DemoServerConfiguration : mir::DefaultServerConfiguration
{
What is going on here ": mir::DefaultServerConfiguration"?
Inside that struct there's this
std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy()
{
return shell_placement_strategy(
[this]
{
return std::make_shared<me::FullscreenPlacementStrategy>(the_display());
});
}
Same story here, i don't understand the syntax the unclear parts are:
<msh::PlacementStrategy> the_shell_placement_strategy()
and
return shell_placement_strategy(
[this]
{
Inside the same struct again
std::initializer_list<std::shared_ptr<mi::EventFilter> const> the_event_filters() override
{
return filter_list;
}
Why the multiple <> <> <> nested? Why the the_event_filters() there?
And the last piece
mir::run_mir(config, [&config, &wm](mir::DisplayServer&)
{
code
});
Unclear part
(config, [&config, &wm](mir::DisplayServer&)
);
First example
That's simply a case of inheriting from an internal type:
class C
{
public:
class Internal
{
};
};
class D : public C::Internal
{
// D derives from Internal class, which is a member of C class
};
The :: is an operator of scope resolution. The expression A::B means: "B, which is a member of A". :: works for classes, structures and namespaces.
Second example
That's a little bit more complicated.
std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy()
{
return shell_placement_strategy(
[this]
{
return std::make_shared<me::FullscreenPlacementStrategy>(the_display());
});
}
Let's break it to parts.
std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy()
This is a function / method the_shell_placement_strategy, which returns a result of type std::shared_ptr (generic class parametrized with msh::PlacementStrategy - see previous point).
return shell_placement_strategy(
It returns result of calling the shell_placement_strategy...
[this]
{
return std::make_shared<me::FullscreenPlacementStrategy>(the_display());
}
...which takes a lambda (nameless function) as a parameter. That nameless function wants to have access to this (thus [this]) and returns result of call to generic function std::make_shared, parametrized with me::FulscreenPlacementStrategy and called with parameter being a result of calling the_display() method / function.
You may read about lambdas elsewhere, but I'll include a short explanation for reference:
[access-specification](parameters){ body }
Where:
access-specification defines the relation between lambda and local variables. For example, [a] means, that lambda will have access to local variable a by value; [&a] - the same, but by reference; [&] - lambda will have access to all local variables by reference and so on.
parameters - regular definition of function parameters
body - regular body of lambda.
The lambda notation is a part of C++11 standard.
Last example
You now should be able to interpret this example:
mir::run_mir(config, [&config, &wm](mir::DisplayServer&)
{
code
});
Thats:
A call to run_mir method (or function), which is a part of mir class (or namespace);
With two parameters: config and a function, which accepts two parameters;
config is passed as first parameter;
A lambda is passed by the second parameter.
Now the lambda:
It wants to access by reference two local variables: config and wm
It accepts one parameter of type mir::DisplayServer& (there's no name for this parameter, so it seems, that it does not actually use it
It does <code> :)
First case, it is private inheritance. DemoServerConfiguration is derived from mir::DefaultServerConfiguration, where mir is probably a namespace (but could also be a class that declares the inner class DefaultServerConfiguration.
Second case, you are looking at lambda expression definition. You can read some introduction here.
Finally, the initializer lists are actually another feature introduced in C++11 standard (not yet supported by most of the compilers, AFAIK). Some introduction about them here.
mir::DefaultServerConfiguration
Here mir could be a namespace or a class inside which DefaultServerConfiguration is defined. So for example, it could be this:
namespace mir
{
class DefaultServerConfiguration
{
/*...*/
};
}
Or this,
class mir
{
public:
class DefaultServerConfiguration
{
/*...*/
};
}
In both cases, you could access the class DefaultServerConfiguration as:
mir::DefaultServerConfiguration
The same is true for other cases.
struct DemoServerConfiguration : mir::DefaultServerConfiguration
{
Here DemoServerConfiguration is a class deriving from mir::DefaultServerConfiguration. Make sense?
You also notice this in case of std::make_shared. Here std is a namespace defined by C++ Standard Library inside which the library defines make_shared function template.
Hope that helps.

How to use pure in D 2.0

While playing around with D 2.0 I found the following problem:
Example 1:
pure string[] run1()
{
string[] msg;
msg ~= "Test";
msg ~= "this.";
return msg;
}
This compiles and works as expected.
When I try to wrap the string array in a class I find I can not get this to work:
class TestPure
{
string[] msg;
void addMsg( string s )
{
msg ~= s;
}
};
pure TestPure run2()
{
TestPure t = new TestPure();
t.addMsg("Test");
t.addMsg("this.");
return t;
}
This code will not compile because the addMsg function is impure. I can not make that function pure since it alters the TestPure object.
Am i missing something? Or is this a limitation?
The following does compile:
pure TestPure run3()
{
TestPure t = new TestPure();
t.msg ~= "Test";
t.msg ~= "this.";
return t;
}
Would the ~= operator not been implemented as a impure function of the msg array? How come the compiler does not complain about that in the run1 function?
Since v2.050, D relaxed the definition of pure to accept the so called "weakly pure" functions too. This refers to functions that "do not read or write any global mutable state". Weakly pure functions are not the same as pure functions in the functional language sense. The only relation is that they makes real pure functions, a.k.a. "strongly pure" functions able call the weak ones, like OP's example.
With this, addMsg can be marked as (weakly) pure, since only the local variable this.msg is altered:
class TestPure
{
string[] msg;
pure void addMsg( string s )
{
msg ~= s;
}
};
and of course, now you can use the (strongly) pure function run2 with no modification.
pure TestPure run2()
{
TestPure t = new TestPure();
t.addMsg("Test");
t.addMsg("this.");
return t;
}
Others have already pointed out that addMsg is not pure and cannot be pure because it mutates the state of the object.
The only way to make it pure is to encapsulate the changes you're making. The easiest way to do this is via return mutation, and there are two ways to implement this.
Firstly, you could do it like this:
class TestPure
{
string[] msg;
pure TestPure addMsg(string s)
{
auto r = new TestPure;
r.msg = this.msg.dup;
r.msg ~= s;
return r;
}
}
You need to copy the previous array because inside a pure function, the this reference is actually const. Note that you could do the copy better by allocating a new array of the final size and then copying the elements in yourself. You would use this function like so:
pure TestPure run3()
{
auto t = new TestPure;
t = t.addMsg("Test");
t = t.addMsg("this.");
return t;
}
This way, the mutation is confined to each pure function with changes passed out via return values.
An alternate way of writing TestPure would be to make the members const and do all the mutation before passing it to the constructor:
class TestPure
{
const(string[]) msg;
this()
{
msg = null;
}
this(const(string[]) msg)
{
this.msg = msg;
}
pure TestPure addMsg(string s)
{
return new TestPure(this.msg ~ s);
}
}
Hope that helps.
Please review the definition of pure functions:
http://en.wikipedia.org/wiki/Pure_function
http://www.digitalmars.com/d/2.0/function.html#pure-functions
Pure functions are functions that produce the same result for the same arguments. To that end, a pure function:
has parameters that are all invariant or are implicitly convertible to invariant
does not read or write any global mutable state
One of the effects of using pure functions is that they can be safely parallelized. However, it's not safe to execute several instances of your function in parallel, because they could both modify the class instance simultaneously, causing a synchronization problem.
I think that your code is conceptually correct. However you may have found case where the compiler's semantic analysis is not as good as your brain's.
Consider the case where the class's source is not available. In that cases the compiler would have no way of telling that addMsg only modifies member variable so it can't allow you to call it from a pure function.
To allow it in your case, it would have to have special case handling for this type of usage. Every special case rule added makes the language more complicated (or, if left undocumented, makes it less portable)
Just a hunch, but this function doesn't always return the same result.
See, it returns a reference to some object, and while the object will always contain the same data, the objects returned by several calls to the same functions are not identical; that is, they don't have the same memory address.
When you return a reference to the object, you're essentially returning a memory address, which is going to be different across several calls.
Another way to think of it, part of the return value is the memory address of an object, which is dependent on some global state(s), and if the output of a function depends on global state, then it's not pure. Hell, it doesn't even have to depend on it; as long as a function reads a global state, then it's not pure. By calling "new", you are reading global state.