/*
* Copyright (c) 2006-2011 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit;
import java.util.*;
import org.junit.*;
import static java.util.Arrays.*;
import static org.junit.Assert.*;
@SuppressWarnings({"UnusedDeclaration"})
public final class ForEachInvocationTest
{
static class Collaborator
{
Collaborator() {}
Collaborator(int i) {}
int getValue() { return -1; }
void doSomething() {}
void doSomething(int i) {}
String doSomething(boolean b, int[] i, String s) { return s + b + i[0]; }
static boolean staticMethod() { return true; }
static boolean staticMethod(int i) { return i > 0; }
native long nativeMethod(boolean b);
final char finalMethod() { return 's'; }
private void privateMethod(short s) {}
void addElements(Collection<String> elements) { elements.add("one element"); }
}
@Test
public void recordExpectationsWithHandlersForEachInvocation()
{
Collaborator collaborator = new Collaborator();
final boolean bExpected = true;
final int[] iExpected = new int[0];
final String sExpected = "test";
new Expectations()
{
Collaborator mock;
{
mock.getValue(); forEachInvocation = new Object() { int getValue() { return 2; } };
mock.doSomething(bExpected, iExpected, sExpected);
forEachInvocation = new Object()
{
String invoked(Boolean b, int[] i, String s)
{
assertEquals(bExpected, b);
assertArrayEquals(iExpected, i);
assertEquals(sExpected, s);
return "";
}
};
}
};
assertEquals(2, collaborator.getValue());
assertEquals("", collaborator.doSomething(bExpected, iExpected, sExpected));
}
@Test
public void verifyExpectationsWithHandlersForEachInvocation(final Collaborator mock)
{
Collaborator collaborator = new Collaborator();
collaborator.addElements(asList("a", "B", "c"));
collaborator.addElements(asList("B", "123"));
collaborator.doSomething(true, new int[0], "test");
new Verifications()
{
{
//noinspection unchecked
mock.addElements((Collection<String>) any);
forEachInvocation = new Object()
{
void verify(Collection<String> elements) { assert elements.contains("B"); }
};
mock.doSomething(anyBoolean, null, null);
forEachInvocation = new Object()
{
void invoked(Boolean b, int[] i, String s)
{
assertTrue(b);
assertArrayEquals(new int[0], i);
assertEquals("test", s);
}
};
}
};
}
@Test
public void returnsMultipleReturnValuesThroughSingleHandler(final Collaborator collaborator)
{
new NonStrictExpectations()
{
{
collaborator.getValue();
forEachInvocation = new Object()
{
int i = 1;
int getValue() { return i++; }
};
}
};
assertEquals(1, collaborator.getValue());
assertEquals(2, collaborator.getValue());
assertEquals(3, collaborator.getValue());
}
@Test
public void recordExpectationWithHandlerForEachInvocationOfConstructor()
{
final ConstructorHandler handler = new ConstructorHandler();
new Expectations()
{
Collaborator mock;
{
new Collaborator(anyInt); forEachInvocation = handler;
}
};
new Collaborator(4);
assertTrue(handler.capturedArgument > 0);
}
static class ConstructorHandler
{
int capturedArgument;
void init(int i) { capturedArgument = i; }
}
@Test
public void verifyExpectationWithHandlerForEachInvocationOfConstructor(Collaborator mock)
{
final Collaborator[] collaborators =
{new Collaborator(5), new Collaborator(4), new Collaborator(1024)};
new FullVerifications()
{
{
new Collaborator(anyInt);
forEachInvocation = new Object()
{
void checkIt(Invocation invocation, int i)
{
assert i > 0;
Collaborator collaborator = collaborators[invocation.getInvocationIndex()];
assert collaborator == invocation.getInvokedInstance();
}
};
}
};
}
@Test(expected = AssertionError.class)
public void verifyExpectationWithHandlerWhichFailsAssertion(Collaborator mock)
{
new Collaborator(0);
new FullVerifications()
{
{
new Collaborator(anyInt);
forEachInvocation = new Object()
{
void checkIt(int i) { assert i > 0; }
};
}
};
}
@Test
public void recordExpectationWithHandlerForStaticMethod()
{
new Expectations()
{
final Collaborator unused = null;
{
Collaborator.staticMethod();
forEachInvocation = new Delegate() { boolean staticInvocation() { return false; } };
}
};
assertFalse(Collaborator.staticMethod());
}
@Test
public void verifyExpectationsOnStaticMethodsWithHandlers(Collaborator unused)
{
Collaborator.staticMethod();
Collaborator.staticMethod(1);
Collaborator.staticMethod(2);
Collaborator.staticMethod(3);
new FullVerificationsInOrder()
{
{
Collaborator.staticMethod();
forEachInvocation = new Object() { boolean staticInvocation() { return false; } };
Collaborator.staticMethod(1);
forEachInvocation = new Object() { void verify(int i) { assert i == 1; } };
Collaborator.staticMethod(anyInt); times = 2;
forEachInvocation = new Object() { void verify(int i) { assert i == 2 || i == 3; } };
}
};
}
@Test
public void recordExpectationWithInvocationHandlerWhichDefinesStaticHandlerMethod()
{
new NonStrictExpectations()
{
Collaborator mock;
{
mock.doSomething(anyBoolean, null, null);
//noinspection InstantiationOfUtilityClass
forEachInvocation = new StaticDelegate();
}
};
assertEquals("test", new Collaborator().doSomething(false, null, "replay"));
}
static final class StaticDelegate
{
static String verifyArgs(boolean b, int[] i, String s)
{
assertFalse(b);
assertNull(i);
assertEquals("replay", s);
return "test";
}
}
@Test
public void verifyExpectationWithHandlerForNativeMethod(@NonStrict final Collaborator mock)
{
new Collaborator().nativeMethod(true);
new Verifications()
{
{
mock.nativeMethod(anyBoolean);
forEachInvocation = new Object()
{
void verify(boolean b) { assertTrue(b); }
};
}
};
}
@Test
public void recordExpectationWithHandlerForFinalMethod()
{
new Expectations()
{
@NonStrict Collaborator mock;
{
mock.finalMethod();
forEachInvocation = new Object() { char finalMethod() { return 'M'; } };
}
};
assertEquals('M', new Collaborator().finalMethod());
}
@Test
public void verifyExpectationWithHandlerForPrivateMethod(
@NonStrict final Collaborator collaborator)
{
collaborator.privateMethod((short) 5);
new VerificationsInOrder()
{
{
invoke(collaborator, "privateMethod", (short) 5); times = 1;
forEachInvocation = new Object() { void privateMethod(int i) { assert i == 5; } };
}
};
}
@Test
public void recordExpectationWithHandlerForMethodWithCompatibleButDistinctParameterType()
{
new Expectations()
{
@NonStrict Collaborator collaborator;
{
collaborator.addElements(this.<Collection<String>> withNotNull());
forEachInvocation = new Object()
{
void addElements(Collection<String> elements) { elements.add("test"); }
};
}
};
List<String> elements = new ArrayList<String>();
new Collaborator().addElements(elements);
assertTrue(elements.contains("test"));
}
@Test
public void recordExpectationWithHandlerDefiningTwoMethods(final Collaborator collaborator)
{
new NonStrictExpectations()
{
{
collaborator.doSomething(true, null, "str");
forEachInvocation = new Object()
{
void doSomething(boolean b, int[] i, String s) { assert b; }
private String someOther() { return ""; }
};
}
};
assertNull(collaborator.doSomething(true, null, "str"));
}
@Test
public void verifyExpectationWithHandlerDefiningTwoNonPrivateMethods(
final Collaborator collaborator)
{
collaborator.doSomething(true, null, "str");
new Verifications()
{
{
collaborator.doSomething(true, null, "str");
try {
forEachInvocation = new Object()
{
void doSomething(boolean b, int[] i, String s) { assert b; }
void someOther() {}
};
fail();
}
catch (IllegalArgumentException e) {
assert e.getMessage().startsWith("");
}
}
};
}
@Test
public void recordExpectationWithHandlerMissingNonPrivateMethod(final Collaborator collaborator)
{
new NonStrictExpectations()
{
{
collaborator.doSomething(true, null, "str");
try {
forEachInvocation = new Object()
{
private String someOther() { return ""; }
private void doSomethingElse(boolean b, int[] i, String s) {}
};
fail();
}
catch (IllegalArgumentException e) {
assert e.getMessage().startsWith("No non-private ");
}
}
};
}
@Test(expected = AssertionError.class)
public void handlerForFailedUnorderedVerification(final Collaborator mock)
{
mock.doSomething();
new Verifications()
{
{
mock.doSomething(); minTimes = 2;
forEachInvocation = new Object() { void verify() {} };
}
};
}
@Test(expected = AssertionError.class)
public void handlerForFailedOrderedVerification(final Collaborator mock)
{
mock.doSomething();
new VerificationsInOrder()
{
{
mock.doSomething(); maxTimes = 0;
forEachInvocation = new Object() { void verify() {} };
}
};
}
@Test
public void verifyOrderedExpectationsWithHandlerForMultipleInvocations(final Collaborator mock)
{
mock.doSomething(1);
mock.doSomething(2);
mock.doSomething(3);
final SequentialInvocationHandler handler = new SequentialInvocationHandler();
new VerificationsInOrder()
{
{
mock.doSomething(anyInt);
forEachInvocation = handler;
times = 3;
}
};
assertEquals(3, handler.index);
}
static class SequentialInvocationHandler
{
int index;
void verify(int i) { index++; assert i == index; }
}
@Test
public void verifyUnorderedExpectationsWithHandlerForMultipleInvocations(final Collaborator mock)
{
mock.doSomething(1);
mock.doSomething(2);
mock.doSomething(3);
final SequentialInvocationHandler handler = new SequentialInvocationHandler();
new FullVerifications()
{
{
mock.doSomething(anyInt);
forEachInvocation = handler;
times = 3;
}
};
assertEquals(3, handler.index);
}
@Test
public void verifyExpectationWithHandlerWhichDefinesInvocationParameter(final Collaborator mock)
{
mock.doSomething(1);
mock.doSomething();
mock.doSomething(2);
mock.doSomething(3);
mock.finalMethod();
mock.doSomething(4);
final Object handler = new Object()
{
void verify(Invocation invocation, int i)
{
assert mock == invocation.getInvokedInstance();
assert i == invocation.getInvocationCount();
}
};
new VerificationsInOrder()
{
{
mock.doSomething(anyInt);
forEachInvocation = handler;
}
};
new Verifications()
{
{
mock.doSomething(anyInt);
forEachInvocation = handler;
}
};
}
@Test
public void verifyInvocationsWithHandlersHavingAlsoRecordedExpectations(final Collaborator mock)
{
new NonStrictExpectations()
{{
mock.doSomething(anyInt);
mock.doSomething(anyBoolean, null, null);
result = new Delegate()
{
String delegate(boolean b, int[] i, String s)
{
assertTrue(b);
assertNotNull(i);
assertEquals("test", s);
return "mocked";
}
};
}};
assertEquals("mocked", mock.doSomething(true, new int[0], "test"));
mock.doSomething(1);
assertEquals("mocked", mock.doSomething(true, new int[0], "test"));
new Verifications()
{{
mock.doSomething(anyInt); times = 1;
forEachInvocation = new Object()
{
void validate(int i) { assertEquals(1, i); }
};
}};
new VerificationsInOrder()
{{
mock.doSomething(anyBoolean, null, null);
forEachInvocation = new Object()
{
void validate(boolean b, int[] i, String s)
{
assertTrue(b);
assertNotNull(i);
assertEquals("test", s);
}
};
}};
}
}