package org.testory;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.testory.Testory.mock;
import static org.testory.Testory.onInstance;
import static org.testory.Testory.onRequest;
import static org.testory.Testory.onReturn;
import static org.testory.proxy.Invocation.invocation;
import static org.testory.testing.Fakes.newObject;
import static org.testory.testing.HamcrestMatchers.hasMessage;
import java.lang.reflect.Method;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.testory.proxy.InvocationMatcher;
public class TestInvocationMatchers {
private Mockable mock, otherMock;
private InvocationMatcher invocationMatcher;
private Object argument, otherArgument;
private Method method, otherMethod, otherTypeMethod;
private List<Object> arguments, otherArguments;
private Class<?> type;
@Before
public void before() throws NoSuchMethodException {
type = Returnable.class;
mock = mock(Mockable.class);
otherMock = mock(Mockable.class);
argument = newObject("argument");
otherArgument = newObject("otherArgument");
arguments = asList(argument);
otherArguments = asList(otherArgument);
method = Mockable.class.getDeclaredMethod("returnReturnable", Object.class);
otherMethod = Mockable.class.getDeclaredMethod("returnOtherReturnable", Object.class);
otherTypeMethod = Mockable.class.getDeclaredMethod("returnObject", Object.class);
}
@Test
public void on_instance_matches_invocation_on_same_instance() {
invocationMatcher = onInstance(mock);
assertTrue(invocationMatcher.matches(invocation(method, mock, arguments)));
assertTrue(invocationMatcher.matches(invocation(otherMethod, mock, arguments)));
assertFalse(invocationMatcher.matches(invocation(method, otherMock, arguments)));
assertTrue(invocationMatcher.matches(invocation(method, mock, otherArguments)));
}
@Test
public void on_return_matches_invocation_of_method_returning_same_type() {
invocationMatcher = onReturn(type);
assertTrue(invocationMatcher.matches(invocation(method, mock, arguments)));
assertTrue(invocationMatcher.matches(invocation(otherMethod, mock, arguments)));
assertFalse(invocationMatcher.matches(invocation(otherTypeMethod, mock, arguments)));
assertTrue(invocationMatcher.matches(invocation(method, otherMock, arguments)));
assertTrue(invocationMatcher.matches(invocation(method, mock, otherArguments)));
}
@Test
public void on_request_matches_invocation_of_method_returning_same_type_and_equal_arguments() {
invocationMatcher = onRequest(type, arguments.toArray());
assertTrue(invocationMatcher.matches(invocation(method, mock, arguments)));
assertTrue(invocationMatcher.matches(invocation(otherMethod, mock, arguments)));
assertFalse(invocationMatcher.matches(invocation(otherTypeMethod, mock, arguments)));
assertTrue(invocationMatcher.matches(invocation(method, otherMock, arguments)));
assertFalse(invocationMatcher.matches(invocation(method, mock, otherArguments)));
}
@Test
public void invocation_matchers_are_printable() {
assertEquals("onInstance(" + mock + ")", onInstance(mock).toString());
assertEquals("onReturn(" + type.getName() + ")", onReturn(type).toString());
assertEquals("onRequest(" + type.getName() + ", " + argument + ")",
onRequest(type, argument).toString());
assertEquals("onRequest(" + type.getName() + ")", onRequest(type).toString());
}
@Test
public void invocation_matchers_checks_arguments() {
try {
onInstance(null);
fail();
} catch (TestoryException e) {}
try {
onInstance(new Object());
fail();
} catch (TestoryException e) {
assertThat(e, hasMessage("expected mock"));
}
try {
onReturn(null);
fail();
} catch (TestoryException e) {}
try {
onRequest(null);
fail();
} catch (TestoryException e) {}
try {
onRequest(type, (Object[]) null);
fail();
} catch (TestoryException e) {}
}
private static class Returnable {}
private static abstract class Mockable {
abstract Returnable returnReturnable(Object o);
abstract Returnable returnOtherReturnable(Object o);
abstract Object returnObject(Object o);
}
}