Is it possible using variables of ArgumentMatchers? - mockito

Let's say I have an interface looks like this.
interface Some {
/**
* Does some on specified array with specified index and returns the array.
*
* #param array the array.
* #param index the index.
* #returns given {#code array}.
*/
byte[] some(byte[] array, int index);
}
Here comes a simple stubbing make the some method just return given array.
Some some = spy(Some.class);
when(some.some(any(), anyInt())
.thenAnswer(i -> i.getArguments(0)};
Is it possible or does it make any sense modifying above code like this?
Some some = spy(Some.class);
byte[] array = any(); // ##?
int index = anyInt(); // ##?
when(some.some(array, index) // ##?
.thenAnswer(i -> i.getArguments(0)};
Does it have same or equivalent effects?

In the code posted, the test passes and the effect is equivalent. This is not true in the general case, and you can easily break the code.
For example this works:
Some some = mock(Some.class);
byte[] any = any();
int index = anyInt();
when(some.some(any, index)).thenAnswer(i -> i.getArguments()[0]);
var res = some.some(new byte[]{1, 2}, 4);
While this with reordered variables does not work:
Some some = mock(Some.class);
int index = anyInt();
byte[] any = any();
when(some.some(any, index)).thenAnswer(i -> i.getArguments()[0]);
var res = some.some(new byte[]{1, 2}, 4);
Please refer to How do Mockito matchers work?:
Implementation details
Matchers are stored (as Hamcrest-style object matchers) in a stack contained in a class called ArgumentMatcherStorage. MockitoCore and Matchers each own a ThreadSafeMockingProgress instance, which statically contains a ThreadLocal holding MockingProgress instances. It's this MockingProgressImpl that holds a concrete ArgumentMatcherStorageImpl. Consequently, mock and matcher state is static but thread-scoped consistently between the Mockito and Matchers classes.
Most matcher calls only add to this stack, with an exception for matchers like and, or, and not. This perfectly corresponds to (and relies on) the evaluation order of Java, which evaluates arguments left-to-right before invoking a method:
when(foo.quux(anyInt(), and(gt(10), lt(20)))).thenReturn(true);
[6] [5] [1] [4] [2] [3]
This will:
Add anyInt() to the stack.
Add gt(10) to the stack.
Add lt(20) to the stack.
Remove gt(10) and lt(20) and add and(gt(10), lt(20)).
Call foo.quux(0, 0), which (unless otherwise stubbed) returns the default value false. Internally Mockito marks quux(int, int) as the most recent call.
Call when(false), which discards its argument and prepares to stub method quux(int, int) identified in 5. The only two valid states are with stack length 0 (equality) or 2 (matchers), and there are two matchers on the stack (steps 1 and 4), so Mockito stubs the method with an any() matcher for its first argument and and(gt(10), lt(20)) for its second argument and clears the stack.
This demonstrates a few rules:
Mockito can't tell the difference between quux(anyInt(), 0) and quux(0, anyInt()). They both look like a call to quux(0, 0) with one int matcher on the stack. Consequently, if you use one matcher, you have to match all arguments.
Call order isn't just important, it's what makes this all work. Extracting matchers to variables generally doesn't work, because it usually changes the call order. Extracting matchers to methods, however, works great.
int between10And20 = and(gt(10), lt(20));
/* BAD */ when(foo.quux(anyInt(), between10And20)).thenReturn(true);
// Mockito sees the stack as the opposite: and(gt(10), lt(20)), anyInt().
public static int anyIntBetween10And20() { return and(gt(10), lt(20)); }
/* OK */ when(foo.quux(anyInt(), anyIntBetween10And20())).thenReturn(true);
// The helper method calls the matcher methods in the right order.

Related

COleDateTime::SetDateTime and noexcept (code analysis)

See this code:
COleDateTime CSpecialEventDlg::GetSpecialEventDate() noexcept
{
COleDateTime datEvent;
if (datEvent.SetDateTime(m_datEvent.GetYear(),
m_datEvent.GetMonth(),
m_datEvent.GetDay(),
0, 0, 0) != 0)
{
// Error
}
return datEvent;
}
My code analysis said I could add noexcept (which I did). But I decided to investigate a little more. I noticed that SetDateTime returns a value:
Zero if the value of this COleDateTime object was set successfully; otherwise, 1. This return value is based on the DateTimeStatus enumerated type. For more information, see the SetStatus member function.
For that latter function (SetStatus) it states:
The status parameter value is defined by the DateTimeStatus enumerated type, which is defined within the COleDateTime class. See COleDateTime::GetStatus for details.
Now, the documentation for GetStatus is documented to have a definition of:
DateTimeStatus GetStatus() const throw();
So, it throws an exception if there is an error. Therefore, I decided to look at the MFC source for SetDateTime:
inline int COleDateTime::SetDateTime(
_In_ int nYear,
_In_ int nMonth,
_In_ int nDay,
_In_ int nHour,
_In_ int nMin,
_In_ int nSec) throw()
{
SYSTEMTIME st;
::ZeroMemory(&st, sizeof(SYSTEMTIME));
st.wYear = WORD(nYear);
st.wMonth = WORD(nMonth);
st.wDay = WORD(nDay);
st.wHour = WORD(nHour);
st.wMinute = WORD(nMin);
st.wSecond = WORD(nSec);
m_status = ConvertSystemTimeToVariantTime(st) ? valid : invalid;
return m_status;
}
It uses ConvertSystemTimeToVariantTime to set the status. That uses:
inline BOOL COleDateTime::ConvertSystemTimeToVariantTime(_In_ const SYSTEMTIME& systimeSrc)
{
return AtlConvertSystemTimeToVariantTime(systimeSrc,&m_dt);
}
And that uses:
inline BOOL AtlConvertSystemTimeToVariantTime(
_In_ const SYSTEMTIME& systimeSrc,
_Out_ double* pVarDtTm)
{
ATLENSURE(pVarDtTm!=NULL);
//Convert using ::SystemTimeToVariantTime and store the result in pVarDtTm then
//convert variant time back to system time and compare to original system time.
BOOL ok = ::SystemTimeToVariantTime(const_cast<SYSTEMTIME*>(&systimeSrc), pVarDtTm);
SYSTEMTIME sysTime;
::ZeroMemory(&sysTime, sizeof(SYSTEMTIME));
ok = ok && ::VariantTimeToSystemTime(*pVarDtTm, &sysTime);
ok = ok && (systimeSrc.wYear == sysTime.wYear &&
systimeSrc.wMonth == sysTime.wMonth &&
systimeSrc.wDay == sysTime.wDay &&
systimeSrc.wHour == sysTime.wHour &&
systimeSrc.wMinute == sysTime.wMinute &&
systimeSrc.wSecond == sysTime.wSecond);
return ok;
}
At this point I have got lost. In short, I am assuming that SetDateTime does not throw an exception.
I understand this much, if I decide to make a call to GetStatus inside the if clause then we do have a potential for exception to be thrown.
All three MFC functions for which you have shown the source code (COleDateTime::SetDateTime, COleDateTime::ConvertSystemTimeToVariantTime and AtlConvertSystemTimeToVariantTime) have – according to their declarations – the potential to throw exceptions (because they have no specification to the contrary, such as noexcept).
However, that doesn't mean that they will (or are even likely to). Digging a bit further into the MFC source code, the only place I can see, in those three functions, where an exception could be thrown is in the ATLENSURE(pVarDtTm!=NULL); line (in the third function).
The ATLENSURE macro is defined as follows:
#define ATLENSURE(expr) ATLENSURE_THROW(expr, E_FAIL)
And ATLENSURE_THROW is, in turn, defined thus:
#define ATLENSURE_THROW(expr, hr) \
do { \
int __atl_condVal=!!(expr); \
ATLASSUME(__atl_condVal); \
if(!(__atl_condVal)) AtlThrow(hr); \
} __pragma(warning(suppress:4127)) while (0)
So, it would seem that, in your code, an exception will be thrown if expr (in the above snippets) is null (the double-bang, !! pseudo-operator makes any non-zero value into 1 and leaves a zero as zero). That expr is the result of the pVarDtTm!=NULL expression, which can only be 0 (false) if the &m_dt argument in the call in your second MFC source excerpt is itself NULL – and, as the address of a member of the class object through which it is being called, that seems improbable (if not impossible).
Another issue you have is that you appear to misunderstand what the throw() specification in the DateTimeStatus GetStatus() const throw(); declaration means. As described here, it is actually (since C++17) an alias for noexcept (or noexcept(true), to be more precise). To specify that a function can throw any type of exception, the throw(...) or noexcept(false) specifications should be used (or use no except/throw specification at all).
So, your last sentence is not really true:
I understand this much, if I decide to make a call to GetStatus inside the if clause then we do have a potential for exception to be
thrown.
Because the GetStatus() function is specified explicitly as non-throwing, and you already have a call to the SetDateTime member function, which (as described above) can throw an exception (but won't, in your code).

Misleading exception message in GatewayMethodInboundMessageMapper with un-annotated parameters

The following code throws a MessagingException with message At most one parameter (or expression via method-level #Payload) may be mapped to the payload or Message. Found more than one on method [public abstract java.lang.Integer org.example.PayloadAndGatewayHeader$ArithmeticGateway.add(int,int)].
#MessagingGateway
interface ArithmeticGateway {
#Gateway(requestChannel = "add.input", headers = #GatewayHeader(name = "operand", expression = "#args[1]"))
Integer add(#Payload final int a, final int b);
}
The desired functionality could be achieved with something like:
#MessagingGateway
interface ArithmeticGateway {
#Gateway(requestChannel = "add.input", headers = #GatewayHeader(name = "operand", expression = "#args[1]"))
#Payload("#args[0]")
Integer add(final int a, final int b);
}
Should the first version also work? Nevertheless I believe the error message could be improved.
A sample project can be found here. Please check org.example.PayloadAndGatewayHeader and org.example.PayloadAndGatewayHeaderTest.
EDIT
The purpose of #GatewayHeader was to show why one may want to have additional parameters that will not be part of the payload but I am afraid it created confusion. Here is a more streamlined example:
#MessagingGateway
interface ArithmeticGateway {
#Gateway(requestChannel = "identity.input")
Integer identity(#Payload final int a, final int unused);
}
Shouldn't the unused parameter be ignored since there is already another one that is annotated with #Payload?
You can't mix parameter annotations (which are static) with expressions (which are dynamic) because the static code analysis can't anticipate what the dynamic expression will resolve to at runtime. It is probably unlikely, but there theoretically could be conditions in the expression. In any case, it can't determine at analysis time that the expression will provide a value for #args[1] at runtime (it could, of course for this simple case, but not all cases are this simple).
Use one or the other; use your second approach or
Integer add(#Payload final int a, #Header("operand") final int b);

Why is a `node-ffi` Callback returning an empty Buffer with `void *` but not with `int *`?

I'm working on implementing a callback using node-ffi with the following signature:
const callback = ffi.Callback('void', ['int', 'void *'], (eMsg, pData) => {
console.log(pData);
console.log(`Buffer deref: ${ref.get(pData)}`);
});
The underlying C library calls this with a void * value for pData. About half of the callbacks actually return an int * value and, in the other half, pData is more complex data (i.e. Struct). The ref.get(pData) ends up being null. If I change the Callback definition to use int * instead of void *, ref.get(pData) returns the correct value. What I can't figure out is why the void * ends up being a Buffer with a size of 0 that does not dereference properly (even when pData is an int *).
I feel like I'm missing something but can't, for the life of me, see what that would be. Can anyone help?
I had a similar problem, and what I did was set the length property of the returned Buffer to the size of the thing that will be returned.
Because it is void * type, node-ffi basically does not know how long of Buffer will be returned to it.
so in this case, pData.length = <size of structure> should fix it.

Constants in Haxe

How do you create public constants in Haxe? I just need the analog of good old const in AS3:
public class Hello
{
public static const HEY:String = "hey";
}
The usual way to declare a constant in Haxe is using the static and inline modifiers.
class Main {
public static inline var Constant = 1;
static function main() {
trace(Constant);
trace(Test.Constant);
}
}
If you have a group of related constants, it can often make sense to use an enum abstract. Values of enum abstracts are static and inline implicitly.
Note that only the basic types (Int, Float, Bool) as well as String are allowed to be inline, for others it will fail with this error:
Inline variable initialization must be a constant value
Luckily, Haxe 4 has introduced a final keyword which can be useful for such cases:
public static final Regex = ~/regex/;
However, final only prevents reassignment, it doesn't make the type immutable. So it would still be possible to add or remove values from something like static final Values = [1, 2, 3];.
For the specific case of arrays, Haxe 4 introduces haxe.ds.ReadOnlyArray which allows for "constant" lists (assuming you don't work around it using casts or reflection):
public static final Values:haxe.ds.ReadOnlyArray<Int> = [1, 2, 3];
Values = []; // Cannot access field or identifier Values for writing
Values.push(0); // haxe.ds.ReadOnlyArray<Int> has no field push
Even though this is an array-specific solution, the same approach can be applied to other types as well. ReadOnlyArray<T> is simply an abstract type that creates a read-only "view" by doing the following:
it wraps Array<T>
it uses #:forward to only expose fields that don't mutate the array, such as length and map()
it allows implicit casts from Array<T>
You can see how it's implemented here.
For non-static variables and objects, you can give them shallow constness as shown below:
public var MAX_COUNT(default, never):Int = 100;
This means you can read the value in the 'default' way but can 'never' write to it.
More info can be found http://adireddy.github.io/haxe/keywords/never-inline-keywords.

JNA - Use structure array as byref argument

I know parts of this issue is covered by some posts here and I have looked at them and tested some but with no luck.
I have this native method signature which should populate the provided CBadgeData structure array with results:
int elc_GetBadges(int nHandle, char* cErr, int* nRecCount, CBadgeData** arr)
The CBadgeData structure is implemented as follows:
package test.elcprog;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
public class CBadgeData extends Structure{
public static class ByReference extends CBadgeData implements Structure.ByReference { }
public int nBadgeID, nTrigger, nExtraData;
public String cName;
public CBadgeData(Pointer pointer){
super(pointer);
}
public CBadgeData(){ }
public String ToString() {
return nBadgeID + "," + nTrigger + "," + nExtraData + "," + cName;
}
#Override
protected List getFieldOrder() {
String[] s = new String[]{"nBadgeID","nTrigger","nExtraData","cName"};
return Arrays.asList(s);
}
}
My last try to craft this argument and call the method looked like this:
CBadgeData.ByReference[] badges = new CBadgeData.ByReference[max_items];
new CBadgeData.ByReference().toArray(badges);
int ret = inst.elc_GetBadges(handle, err, recCount, badges);
It fails with segmentation error.
My Question is what Java type should be provided here as an argument for the native CBadgeData** in the call to elc_GetBadges?
EDIT -1-
Populating the array myself (with or without terminating null pointer) didn't work and caused further Seg crashes. I then used Pointer[] arg as technomage suggested:
Pointer[] pointers = new Pointer[max_items];
for(int i=0; i<max_items; i++){
pointers[i] = new CBadgeData.ByReference().getPointer();
}
int ret = inst.elc_GetBadges(handle, err, recCount, pointers);
This caused no error but seems to not make any changes to the returning struct which should have contain 4 items in this case:
int bid = new CBadgeData(pointers[i]).nBadgeID; // this returns null for all items
Using explicit read() / write() on the struct led to Seg crashes again (on the read):
Any idea what am I still missing here?
EDIT -2-
Interestingly enough - using the Memory.get directly, after calling the native method, gets the correct results:
Memory m= (Memory)pointers[0];
System.out.println("1st int: "+m.getInt(0)); // this gets 24289 which is 5ee1
System.out.println("2nd int: "+m.getInt(4)); // this gets 3
System.out.println("3rd int: "+m.getInt(8)); // this gets 255
System.out.println("String: "+m.getString(12)); // this gets "Badge[5EE1]" as supposed
But the read() still crashes. Any thoughts?
I'm inferring that CBadgeData** input is intended to be an array of pointer to CBadgeData.
As such, the Structure.ByReference tagging is correct.
Structure.toArray() is probably not appropriate here, or at least not necessary (it allocates a contiguous block of structs in memory). You can just populate your array with CBadgeData.ByReference instances.
Perhaps your callee is expecting a NULL pointer at the end of the array? I don't see another indicator of the array length to the callee.
CBadgeData.ByReference[] badges = new CBadgeData.ByReference[max_items+1];
for (int i=0;i < badges.length-1;i++) {
badges[i] = new CBadgeData.ByReference();
}
badges[badges.length-1] = null;
Pretty sure that works. If for whatever reason there's a bug handling Structure.ByReference[], I know that Pointer[] is reliable and will do the same thing.
EDIT
If you use Pointer[] instead of Structure.ByReference[] (please post a bug to the project site if Structure.ByReference[] does not work), you will have to manually call Structure.write/read before/after your native function call, since JNA will not know that the pointers reference structures that need to be synched with native memory. I'd bet, however, that the cause of your crashes when using Structure.ByReference[] was simply that JNA was automatically calling Structure.read() after the call and triggered the same error that you see when calling it explicitly.
If you get a segfault on read, it likely means that your structure fields aren't properly aligned or defined, or (less likely) that you have corrupt data that can't be read properly. To diagnose this, set jna.dump_memory=true and print out your struct after calling Structure.write() to see if the contents of the structure appear as you'd expect. It'd also help to post the native and JNA forms of your structure here, if possible.

Resources