Skip to content

Instantly share code, notes, and snippets.

@superbob
Last active August 17, 2021 12:46
Show Gist options
  • Save superbob/091489c61ce9bd79d14a4d3d731c9c49 to your computer and use it in GitHub Desktop.
Save superbob/091489c61ce9bd79d14a4d3d731c9c49 to your computer and use it in GitHub Desktop.
Use AssertJ assertions in Mockito verify argument matchers
import java.util.function.Consumer;
import org.assertj.core.matcher.AssertionMatcher;
import org.hamcrest.Matcher;
import org.mockito.hamcrest.MockitoHamcrest;
/**
* Allow using AssertJ assertions for mockito matchers.
* @see MockitoHamcrest#argThat(Matcher)
* @see AssertionMatcher
*/
public final class AssertJMatcher
{
private AssertJMatcher() { }
/**
* Adapt a consumer containing AssertJ assertions to an hamcrest {@link Matcher} using an {@link AssertionMatcher}.
* @param assertions a value consumer taking the parameter value as input
* @param <T> type of the parameter
* @return the {@link Matcher}
* @see AssertionMatcher
*/
public static <T> Matcher<T> is(ThrowingConsumer<T> assertions) {
return new AssertionMatcher<T>()
{
@Override
public void assertion(T actual) throws AssertionError
{
try {
assertions.accept(actual);
} catch (Exception e) {
throw new AssertionError(e);
}
}
};
}
/**
* Matches using AssertJ assertions. Shorthand to <code>MockitoHamcrest.argThat(is(...))</code>
* @param assertions a value consumer taking the parameter value as input
* @param <T> type of the parameter
* @return <code>null</code>
* @see MockitoHamcrest#argThat(Matcher)
* @see #is(ThrowingConsumer)
*/
public static <T> T argThat(ThrowingConsumer<T> assertions) {
return MockitoHamcrest.argThat(is(assertions));
}
@FunctionalInterface
public interface ThrowingConsumer<T> {
void accept(T t) throws Exception;
}
}
import static AssertJMatcher.argThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test;
class ExampleTest {
@Test
void aTest() {
// ...
// Let's say you have aMock having aMethod taking a List argument and you want to check the list element values not in order.
// Now you can have:
verify(aMock).aMethod(Matchers.argThat(is(actual -> assertThat(actual).containsExactlyInAnyOrder(aValue, anotherValue))));
// Or even
verify(aMock).aMethod(argThat(actual -> assertThat(actual).containsExactlyInAnyOrder(aValue, anotherValue)));
/*
Instead of something like that:
ArgumentCaptor<List> listCaptor = ArgumentCaptor.forClass(List.class);
verify(aMock).aMethodCall(listCaptor.capture());
assertThat(listCaptor.getValue()).containsExactlyInAnyOrder(aValue, anotherValue);
*/
}
}
@Sam-Kruglov
Copy link

This is better:

import org.assertj.core.matcher.AssertionMatcher;
import org.mockito.hamcrest.MockitoHamcrest;

import java.util.function.Consumer;

public class TestUtil {

    public static <T> T argThat(Consumer<T> assertions) {
        return MockitoHamcrest.argThat(new AssertionMatcher<T>() {
            @Override
            public void assertion(T actual) throws AssertionError {
                assertions.accept(actual);
            }
        });
    }
}

.....

verify(aMock).aMethod(argThat(actual -> assertThat(actual).containsExactlyInAnyOrder(aValue, anotherValue)));

@superbob
Copy link
Author

superbob commented Aug 17, 2021

This is better:

import org.assertj.core.matcher.AssertionMatcher;
import org.mockito.hamcrest.MockitoHamcrest;

import java.util.function.Consumer;

public class TestUtil {

    public static <T> T argThat(Consumer<T> assertions) {
        return MockitoHamcrest.argThat(new AssertionMatcher<T>() {
            @Override
            public void assertion(T actual) throws AssertionError {
                assertions.accept(actual);
            }
        });
    }
}

.....

verify(aMock).aMethod(argThat(actual -> assertThat(actual).containsExactlyInAnyOrder(aValue, anotherValue)));

Thanks for the suggestion.
That was an old gist I didn't update since ages.
I've improved the code it was based on since then. But I didn't update the gist.
Thanks again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment