Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using hamcrest matchers with primitive type arrays

Hamcrest works well for primitive data types due to automatic boxing and unboxing like in this case:

assertThat(1, is(1));

However, I would like to use hamcrest's hasItemInArray matcher with a primitive type array like this:

int[] values = someMethodCall();
assertThat(values, hasItemInArray(1));

Since there is no automatic boxing/unboxing for arrays of primitive data types the above code does not compile. Is there any preferred way of accomplishing the above, other than manually converting from int[] to Integer[]?

like image 246
k13n Avatar asked Sep 07 '25 18:09

k13n


3 Answers

When you do static loading and dynamic linking of a shared library

You don't do 'static loading' of a shared library.

Even though it looks to you as an end-user that e.g. libc.so.6 is 'static loaded' at process startup, it is not in fact the case. Rather, the kernel 'static loads' the main binary and ld-linux.so, and then ld-linux dynamic loads all the other shared libraries.

does this linking patch my binary's references like in the static loading & linking scenario, or does it work by way of function pointers like in the case of dynamic loading

It depends.

Usually shared libraries are linked from position-independent code (PIC), and work the way of function pointers (the pointers are stored in the GOT -- global offset table).

But sometimes shared libraries are linked from non-PIC code, and require "text relocations", which work similar to "static linking".

like image 182
Employed Russian Avatar answered Sep 11 '25 07:09

Employed Russian


AFAIK there isn't an automatic way of achieving this. If you can make use of 3rd party libraries you might want to check out the Apache Commons Lang library which provides an ArrayUtils class with a conversion method:

Integer[] toObject(int[] array)

int[] values = someMethodCall();
Integer[] objValues = ArrayUtils.toObject(values);
assertThat(objValues , hasItemInArray(1));
like image 36
Stephen Asherson Avatar answered Sep 11 '25 08:09

Stephen Asherson


Here is my solution it also uses Apache Commons ArrayUtils#toObject

With the imports

import static org.apache.commons.lang3.ArrayUtils.toObject;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
import static org.hamcrest.Matchers.hasItemInArray;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;

You can write readable tests like

@Test
void primitiveArrayTest() {
    int[] actual = new int[]{1, 2, 3};

    assertThat(toObject(actual), is(arrayContaining(1, 2, 3)));
    assertThat(toObject(actual), is(arrayContainingInAnyOrder(2, 3, 1)));
    assertThat(toObject(actual), hasItemInArray(2));
    assertThat(toObject(actual), is(not(arrayContaining(-5))));
}

The is is just used to improve the readability.

like image 34
James Mudd Avatar answered Sep 11 '25 07:09

James Mudd