How to use Mockito to verify a function was called either 3 or 6 times? - mockito

In mockito, I can do something like this to verify my function was called exactly 3 times
verify(mock, times(3)).someMethod("was called three times");
But sometimes, it can be called 6 times, causing the test to fail. (This is because the test relies on an at-least-once-delivery queue, and the function will be called 6 times when the queue delivers a second time).
How can I assert someMethod is called 3 times OR 6 times, but fail if it is called say 4 times?

I think, you can try this kind of behaviour :
try {
Mockito.verify(mock, Mockito.times(3)).someMethod(argumentMatcher);
}
catch(TooManyActualInvocations e) {
Mockito.verify(mock, Mockito.times(6)).someMethod(argumentMatcher);
}

Related

How to ensure the comparison result still hold in multi-threading?

Suppose there are 3 threads,
Thread 1 and 2 will increase or decrease a global variable X atomically.
thread 1:
atomic_increase(X)
thread 2:
atomic_decrease(X)
Thread 3 will check if the X is greater than some predefined value and do things accordingly.
thread 3:
if( X > 5 ) {... logic 1 ...}
else {... logic 2 ....}
I think the atomic_xxx operations are not enough. They can only synchronize the modifications between thread 1 and 2.
What if X is changed by thread 1 or 2 after thread 3 finishes the comparison and enters logic 1.
Do I have to use a mutex to synchronize all the 3 threads when modifying or reading the X?
ADD 1
BTW, logic 1 and logic 2 don't modify the X.
In short yes, reads also need to be synchronized in some way, otherwise the risk of inconsistent reads is real. A read performed between the read and write of atomic_increase will be inconsistent.
However if logic 1 or logic 2 do stuff to X, your problems doesn't seem to stop right there. I think then you need the concept of a transaction, where it starts with a read (the X > 5 thing) and then ends with a write (logic 1 or logic 2).
Yes, And the Answer is happens before link, Lets say Thread-1 started executing atomic_increase method. It will hold the lock and enter the synchronized block to update X.
private void atomic_increase() {
synchronized (lock) {
X = X + 1; // <-- Thread-1 entered synchronized block, yet to update variable X
}
}
Now, for Thread-3 to run the logic, it needs to read the variable X, and if it is not synchronized (on the same monitor), the variable X read can be an old value since it may not yet updated by Thread-1.
private void runLogic() {
if (X > 5) { // <-- Reading X here, can be inconsistent no
happens-before between atomic_increase and runLogic
} else {
}
}
We could have prevented this by maintaining a happens-before link between atomic operation and run_logic method. If the runLogic is synchronized (on the same monitor) , then it would have to wait until the variable X to be updated by the Thread-1. So we are guaranteed to get the last updated value of X
private void runLogic() {
synchronized (lock) {
if (X > 5) { // <-- Reading X here, will be consistent, since there
is happens-before between atomic_increase and runLogic
} else {
}
}
}
The answer depends on what your application does. If neither logic 1 nor logic 2 modifies X, it is quite possible that there is no need for additional synchronization (besides using an atomic_load to read X).
I assume you use intrinsics for atomic operations, and not simply an increment in a mutex (or in a synchronized block in Java). E.g. in Java there is an AtomicInteger class with methods such as 'incrementAndGet' and 'get'. If you use them, there is probably no need for additional synchronization, but it depends what you actually want to achieve with logic 1 or logic 2.
If you want to e.g. display a message when X > 5, then you can do it. By the time the message is displayed the value of X may have already changed, but it remains the fact, that the message was triggered by X being greater than 5 for at least some time.
In other words, without additional synchronization, you have only the guarantee that logic 1 will be called if X becomes greater than 5, but there is no guarantee that it will remain so during execution of logic 1. It may be ok for you, or not.

The function has been called 10 times but the decorator has only been called once. Why?

def call_counter(func):
print('Called\n')
def helper(x):
helper.calls+=1
return func(x)
helper.calls=0
return helper
#call_counter
def succ(x):
return x+1
print(str(succ.calls)+'\n')
for i in range(10):
print(succ.calls)
succ(i)
print('\n')
print(succ.calls)
You commented:
I don't understand why the decorator is called on the function only once. It should be called 10 times, right? One time for every iteration in the loop and therefore 'Called' should be printed 10 times. What am I missing?
I think you are confusing runs of the decorator for runs of the wrapper function (named helper in your code). The decorator is only called once, when it gets passed the original function and returns the wrapper function, which is what gets stored as succ in your module. The wrapper is what gets called ten times by your loop.
When I run your code, this is the output I get:
Called
0
0
1
2
3
4
5
6
7
8
9
10
Only the first two lines ("Called" and the empty line after it) come from the decorator call. You can see this if you run only the function definition, and not the loop. You'll see "Called" printed out immediately, even if you never call the function at all.
The zero at the top and the ten at the bottom are from the print statements you have at the top level. The numbers printed close together are the output of the loop, which prints the count of previous calls just before it makes each new call to the wrapped function.

Branch prediction and multithreading

Let's suppose a simple if like this:
if (something)
// do_something
else
// do_else
Suppose that this if-else statement is executed in parallel in different threads, and each thread yielding a different result, but constant through its own life. For example, in thread 1 the condition is always evaluated as false, in thread 2, true; in thread 3 always true as well, and so on.
Does branch prediction consider the execution context of each thread to make its statistics? Because if it doesn't (I don't think that, but its difficult to check by testing), the CPU will see the condition follows a random pattern and won't predict at all.
If we ignore SMT (f.ex. hyper-threading) most architectures have a branch predictor per hardware thread.
Its tightly coupled with the fetch unit of the individual core. A few (AMD?) store some branch prediction information in L1/L2 I-cache but mostly target for next fetch.
So if you don't run your code on a SMT you are in heaven and will get a 100% predicted every time at the cost of a few instructions.
If you run your code on a SMT you will often find your life is hell, with 50+% mispredict.
Now you can solve your problem easily you just have to use more code, check your condition earlier and call a branch of your code with do_something or do_else in it.
If you have a loop that calls your function where you have your branch you can do something like:
if (something)
do_something_loop();
else
do_else_loop();
void do_something_loop() {
for (auto x : myVec)
do_something;
}
This has the disadvantage that you need to maintain 2 nearly equal branches of code.
Or you can have your branch in a function call branch_me() which you can make a template function and due to the magic of dead code elimination you should not get any branches in the loops.
C++ Concept code.
template<bool b_something>
void brancher() {
// do things
if (b_something)
// do_something
else
// do_else
}
// do more things
}
void branch_user() {
if (something) {
for (auto x : myVec)
brancher<true>();
} else {
for (auto x : myVec)
brancher<false>();
}
}
Now you only have to maintain the 2 branches of the outer function which hopefully is less work.

Stub a method basing on arguments

class ArgumentClass{
int var;
}
class ClassMocked{
int aMothod(ArgumentClass argumentClass){
return anInt;
}
}
class MyTest{
Mock and Stub here
}
In MyTest, I want to stub aMothod such that it returns the value basing on value of ArgumentClass.var. And I have to do it in one go.
In other words, I have a test case where a moehod is called three times by the app code and basing on a variable in an argument object, I need different return values. I need to stub accordingly. Please let me know if there is a way.
If I understand that correctly you can do it in two different way with mockito. If you declare ClassMocked as a mock you should be able to say this:
when(mock.aMothod(eq(specificArgument))).thenReturn(1);
when(mock.aMothod(eq(anotherSpecificArgument))).thenReturn(2);
If you want to do it that regardless of the argument passed you want to return values based on the number of invocation of the method you can say:
when(mock.aMothod(any())).thenReturn(1, 2);
This says that when aMothod is called regardless of the parameter passed (any()) it will return in the first call 1 and when called second time it will return 2.
Though you can have your mock return values in the right order, as in karruma's answer, you may also use an Answer to calculate the mocked value:
when(mock.aMothod(any())).thenAnswer(new Answer<Integer>() {
#Override public Integer answer(InvocationOnMock invocation) {
ArgumentClass argument = invocation.getArguments()[0];
return calculationBasedOn(argument);
}
});
Or in Java 8 and Mockito 2 beta (untested, may need boxing/unboxing casts):
when(mock.aMothod(any())).thenAnswer(invocation ->
calculatebasedOn(invocation.getArgumentAt(0, ArgumentClass.class)));
Though I have an anonymous inner class in the top sample, naturally, you can make a named Answer subclass and reuse it across your application.

Throwing NoSuchElementException for ranges

Lets say I have the following (ideone):
x = [1,2,3]
y = x.iterator();
println y.next();
println y.next();
println y.next();
println y.next();
This outputs:
1
2
3
Caught: java.util.NoSuchElementException
java.util.NoSuchElementException
at java_util_Iterator$next.call(Unknown Source)
at prog.run(prog.groovy:7)
As expected.
But lets change x = [1,2,3] to x = 1..3, so the code is the following (ideone):
x = 1..3
y = x.iterator();
println y.next();
println y.next();
println y.next();
println y.next();
Now we get the output:
1
2
3
null
And no exception is thrown. Why is this the case? It's really unexpected that [1,2,3] and 1..3 behave differently when iterating through them. It seems like such behaviour doesn't comply with iterator's contract.
Is there a way for me to fix this behaviour, and will such a fix break anything else?
Edit: Let me try to be clearer:
This is the correct usage of the Iterator class:
x = 1..3
y = x.iterator();
while(y.hasNext()) {
println y.next();
}
The NoSuchElement exception is an unchecked (AKA runtime) exception. The reason it's not checked is that it's something that should be avoidable completely without relying on the exception. This is different than, for example, IOExceptions, which are checked and far more likely to occur during normal use.
It's not explicitly stated one way or the other in the docs, but the only time I see the next() method throwing a NoSuchElementException when the Iterator is used correctly as above is if you have a modifiable collection in an unsynchronized, multi-threaded environment that has an item removed between the moment you call hasNext and access the item using next.
Because the Range class is unmodifiable, there is no chance, ever, of that situation rising.
You should not rely on unchecked Exceptions to determine the functionality or state of an item.
So, I don't really think the contract has been broken. The contract for using an iterator is to use hasNext before next, and the Range class's Iterator is not required to throw an exception just because it is being used incorrectly.
use :
While(y.hasNext()){
println y.next();
}
It's because IntRangeIterator returns null when it has gone off the end of the Range
As you can see in the source code for it here
I guess if you feel that this is incorrect behaviour, you should ask on the mailing lists, or post a bug to the Groovy JIRA, but as it's been that way for 6 years I would imagine it's going to stay that way (as it would be a breaking change)
As other people say, you should use a for or each mechanism to iterate the Iterator, or if that's not possible wrapping your calls to next() in a hasNext() check should catch all cases where you're off the end.

Resources