Stub a method basing on arguments - mockito

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.

Related

Comparator vs Closure in min call in groovy?

I am trying to understand the difference between passing a Closure vs a Comparator to the min function on a collection:
// Example 1: Closure/field/attribute?
Sample min = container.min { it.timespan.start }
// Example 2: Comparator
Sample min2 = container.min(new Comparator<Sample>() {
#Override
int compare(Sample o1, Sample o2) {
return o1.timespan.start <=> o2.timespan.start
}
})
They both return the correct result.
Where:
class Sample {
TimeSpan timespan
static constraints = {
}
}
And:
class TimeSpan {
LocalDate start
LocalDate end
}
In Example 1 I just pass the field timespan.start to min which I guess means that I am passing a Closure (even though its just a field in a class)?
In Example 1 does groovy convert the field timespan.start into a Comparator behind the scenes like the one I create explicitly in Example 2?
The difference is, that those are two different min methods both
taking different arguments. There is one for passing
a closure
and one for the
comparator
(there is a third one using identity and some deprecated ones, but we can ignore that for now).
The first version (Closure with one (implicit argument)) you have to
extract the value from the passed value, you want to make the min
aggregate with. Therefor this versions has some inner working to deal
with comparing the values.
But the docs also state:
If the closure has two parameters it is used like a traditional
Comparator. I.e. it should compare its two parameters for order,
returning a negative integer, zero, or a positive integer when the
first parameter is less than, equal to, or greater than the second
respectively. Otherwise, the Closure is assumed to take a single
parameter and return a Comparable (typically an Integer) which is then
used for further comparison.
So you can use a Closure version also to the same as your second example
(you have to define two params explicitly):
container.min{ a, b -> a <=> b }
And there is also a shorter version of the second example. You can cast
a Closure to an interface with groovy. So this works too:
container.min({ a, b -> a <=> b } as Comparator)

Can I manipulate the order of mockito matchers?

Some Context
When setting up mocks (when) or verifying calls (verify) on mocks, Mockito requires you to either provide all concrete values a mocked method needs, or provide a matcher for all of them. It is not possible to mix these styles.
when(mock.method(1, 2, 3));
when(mock.method(eq(1), eq(2), eq(3)));
I am talking about the second style.
Because of the way Mockito works, the order in which matchers are called is important. Internally, Mockito will register the matchers on a stack, executing them in order when necessary.
What I try to achieve
I want to write some test utilities to be used with mockito. I would like these utility methods to delegate calls to the mock, interjecting some default matchers that would otherwise be boilerplate test code.
For example:
public String callOnMock(int argument2) {
return mock.call(eq(1), argument2, argThat(i -> i >= 3));
}
which would be used like this:
when(callOnMock(eq(2)).thenReturn("result");
The problem
This does not work because Mockito registers these matchers in the wrong order:
eq(2)
eq(1)
argThat(i -> i >= 3)
while it should be
eq(1)
eq(2)
argThat(i -> i >= 3)
Is there a way for me to manipulate the order that those matchers are registered?
I now that org.mockito.AdditionalMatchers has methods that manipulate the internal stack to allow matchers to be combined (and, or, not) so at least internally inside the Mockito core it is possible.
Is it also possible to pop and push matchers explicitly?
Use a Supplier :
public String callOnMock(Supplier<Integer> argument2) {
return mock.call(eq(1), argument2.get(), argThat(i -> i >= 3));
}
when(callOnMock(() -> eq(2)).thenReturn("result");
Try this:
public String callOnMock(int argument2) {
return mock.call(eq(1), eq(argument2), argThat(i -> i >= 3));
}
and call it like:
when(callOnMock(2)).thenReturn("result");
I think there are a couple of ways to achieve the desired behaviour.
1. Manipulate the order of matchers on the stack
This is not the way to go!
The matcherStack seems to be internal to Mockito.
They do have a method to pullLocalizedMatchers from the stack and a reportMatcher method to push an ArgumentMatcher onto the stack. These could be accessed via
org.mockito.internal.progress.ThreadSafeMockingProgress
.mockingProgress()
.getArgumentMatcherStorage()
So in theory you could choose this path, but the solution would be brittle because you are messing with the internals of Mockito. They could change without notice in subsequent versions of Mockito.
Luckily there are a couple of alternatives.
2. Control the order in which matchers are registered in the first place
Using the Java 8 Supplier functional interface (This corresponds to this answer given by #ToYonos)
Matchers are registered automatically by Mockito when you call the methods creating them (eq, argThat, any, isNotNull, ...). But you can delay calling these methods by passing a Supplier for each of those matchers. The convenience method then controls the order in which it executes those suppliers.
public String callOnMock(Supplier<Integer> argument2) {
return mock.call(eq(1), argument2.get(), argThat(i -> i >= 3));
}
when(callOnMock(() -> eq(2))).thenReturn("result");
Using it looks a bit different than the normal Mockito style.
Special care needs to be taken if you offer convenience methods for those suppliers that use/aggregate other matchers, because of the same problem.
callOnMock(() -> AdditionalMatchers.and(isNotNull(), eq(2)))
will work,
but this will not:
public Supplier<Integer> and(int matcher1, int matcher2){
return () -> AdditionalMatchers.and(matcher1, matcher2);
}
callOnMock(and(isNotNull(), eq(2)))
This puts some responsibility with the user of your methods. They have to make sure that none of the matchers gets called accidentally.
3. Control the order in which mocks expect matchers
Delegating mock calls to a different mock object can give you control over the order of the arguments.
You will have to define an interface that expects matchers in the order your convenience method receives them, putting the ones added by the convenience method at the end.
Expectations have to be made against that delegate interface.
public interface MockDelegate {
String call(Integer i1, Integer i0, Integer i2);
}
#Mock
private MockDelegate delegate;
#Before
public void setUp() {
when(mock.call(any(), any(), any()))
.thenAnswer(invocation -> delegate.call(
invocation.getArgument(1), // this delegates the call
invocation.getArgument(0), // but flips the first two arguments
invocation.getArgument(2)
));
}
public String callOnMock(int argument2) {
return delegate.call(argument2, eq(1), argThat(i -> i >= 3));
}
This can be used with normal Mockito style matchers:
when(callOnMock(eq(2))).thenReturn("result");

Is good to call function in other function parameter?

I suppose this:
public static string abc()
{
return "abc";
}
Is better to call this function in this way:
string call = abc();
Console.writeline(call);
Than this?
console.writeline(abc());
is there any reason to prefer one to the other?
Both are valid. However, out of experience I have concluded that the first option is more suitable for readability and ease of maintenance. I can't count how many times I have changed from the "compact" style to the first one as a help for a debugging session.
For example, this style makes it easy to check the correctness intermediate of an intermediate result:
string call = abc();
assert(!call.empty()); // Just an example.
Console.writeline(call);
Also, it helps to make the code more robust later, adding a conditional check before the subsequent action that checks call's value, for example if the design does not guarantee that the condition of the previous assert holds but you still need to check it.
string call = abc();
if (!call.empty())
{
Console.writeline(call);
}
Note also that with this style you will be able to easily inspect the value of call in your debugger.
Given your exact example (one parameter, value not used elsewhere, no side effects), it's just a matter of style. However, it gets more interesting if there are multiple parameters and the methods have side effects. For example:
int counter;
int Inc() { counter += 1; return counter }
void Foo(int a, int b) { Console.WriteLine(a + " " + b); }
void Bar()
{
Foo(Inc(), Inc());
}
What would you expect Foo to print here? Depending on the language there might not even be a predictable result. In this situation, assigning the values to a variable first should cause the compiler (depending on language) to evaluate the calls in a predictable order.
Actually I don't see a difference if you don't have any error checking.
This would make a difference
string call = abc();
# if call is not empty
{
Console.writeline(call);
}
The above method could avoid empty string being written.

Can we pass many objects as parameter of any method with condition statement

Can we pass many objects as one argument for method parameter with conditional statement
for example
Two class : one and two
Passing method is
public void passe(one||two)
{
}
You can't have conditional arguments on a method the way you described.
If the two arguments are of the same type (or belong to an inheritance chain), you can simply pass in the value conditionally to the method.
Alternatively, you can use optional arguments.
public void passe(typex one = someXdefualt, typey two = someYdefualt)
{
}

Groovy named and default arguments

Groovy supports both default, and named arguments. I just dont see them working together.
I need some classes to support construction using simple non named arguments, and using named arguments like below:
def a1 = new A(2)
def a2 = new A(a: 200, b: "non default")
class A extends SomeBase {
def props
A(a=1, b="str") {
_init(a, b)
}
A(args) {
// use the values in the args map:
_init(args.a, args.b)
props = args
}
private _init(a, b) {
}
}
Is it generally good practice to support both at the same time? Is the above code the only way to it?
The given code will cause some problems. In particular, it'll generate two constructors with a single Object parameter. The first constructor generates bytecode equivalent to:
A() // a,b both default
A(Object) // a set, b default
A(Object, Object) // pass in both
The second generates this:
A(Object) // accepts any object
You can get around this problem by adding some types. Even though groovy has dynamic typing, the type declarations in methods and constructors still matter. For example:
A(int a = 1, String b = "str") { ... }
A(Map args) { ... }
As for good practices, I'd simply use one of the groovy.transform.Canonical or groovy.transform.TupleConstructor annotations. They will provide correct property map and positional parameter constructors automatically. TupleConstructor provides the constructors only, Canonical applies some other best practices with regards to equals, hashCode, and toString.

Resources