/*
* Copyright (c) 2006 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit;
import java.io.*;
import java.util.*;
import org.junit.*;
import org.junit.rules.*;
import static org.junit.Assert.*;
public final class MockInvocationProceedTest
{
@Rule public final ExpectedException thrown = ExpectedException.none();
public static class BaseClassToBeMocked
{
protected String name;
public final int baseMethod(int i) { return i + 1; }
protected int methodToBeMocked(int i) throws IOException { return i; }
}
public static class ClassToBeMocked extends BaseClassToBeMocked
{
public ClassToBeMocked() { name = ""; }
public ClassToBeMocked(String name) { this.name = name; }
public boolean methodToBeMocked() { return true; }
protected int methodToBeMocked(int i, Object... args)
{
int result = i;
for (Object arg : args) {
if (arg != null) result++;
}
return result;
}
public String anotherMethodToBeMocked(String s, boolean b, List<Integer> ints)
{ return (b ? s.toUpperCase() : s.toLowerCase()) + ints; }
public static boolean staticMethodToBeMocked() throws FileNotFoundException { throw new FileNotFoundException(); }
protected static native void nativeMethod();
}
@Test
public void proceedFromMockMethodWithoutParameters()
{
new MockUp<ClassToBeMocked>() {
@Mock boolean methodToBeMocked(Invocation inv) { return inv.proceed(); }
};
assertTrue(new ClassToBeMocked().methodToBeMocked());
}
@Test
public void proceedFromMockMethodWithParameters() throws Exception
{
new MockUp<ClassToBeMocked>() {
@Mock int methodToBeMocked(Invocation inv, int i) { Integer j = inv.proceed(); return j + 1; }
@Mock
private int methodToBeMocked(Invocation inv, int i, Object... args)
{
args[2] = "mock";
return inv.<Integer>proceed();
}
};
ClassToBeMocked mocked = new ClassToBeMocked();
assertEquals(124, mocked.methodToBeMocked(123));
assertEquals(-8, mocked.methodToBeMocked(-9));
assertEquals(7, mocked.methodToBeMocked(3, "Test", new Object(), null, 45));
}
@Test
public void proceedConditionallyFromMockMethod() throws Exception
{
new MockUp<ClassToBeMocked>() {
@Mock
String anotherMethodToBeMocked(Invocation inv, String s, boolean b, List<Number> ints)
{
if (!b) {
return s;
}
ints.add(45);
return inv.proceed();
}
};
ClassToBeMocked mocked = new ClassToBeMocked();
// Do not proceed:
assertNull(mocked.anotherMethodToBeMocked(null, false, null));
// Do proceed:
List<Integer> values = new ArrayList<Integer>();
assertEquals("TEST[45]", mocked.anotherMethodToBeMocked("test", true, values));
// Do not proceed again:
assertEquals("No proceed", mocked.anotherMethodToBeMocked("No proceed", false, null));
}
@Test
public void proceedFromMockMethodWhichThrowsCheckedException() throws Exception
{
new MockUp<ClassToBeMocked>() {
@Mock
boolean staticMethodToBeMocked(Invocation inv) throws Exception
{
if (inv.getInvocationIndex() == 0) {
return inv.<Boolean>proceed();
}
throw new InterruptedException("fake");
}
};
try { ClassToBeMocked.staticMethodToBeMocked(); fail(); } catch (FileNotFoundException ignored) {}
thrown.expect(InterruptedException.class);
ClassToBeMocked.staticMethodToBeMocked();
}
@Test
public void proceedFromMockMethodIntoRealMethodWithModifiedArguments() throws Exception
{
class MockUpWhichModifiesArguments extends MockUp<ClassToBeMocked> {
@Mock
final int methodToBeMocked(Invocation invocation, int i) { return invocation.<Integer>proceed(i + 2); }
}
new MockUpWhichModifiesArguments() {
@Mock
synchronized int methodToBeMocked(Invocation inv, int i, Object... args)
{
return inv.<Integer>proceed(1, 2, "3");
}
};
ClassToBeMocked mocked = new ClassToBeMocked();
assertEquals(3, mocked.methodToBeMocked(1));
assertEquals(3, mocked.methodToBeMocked(-2, null, "Abc", true, 'a'));
}
@Test
public void cannotProceedFromMockMethodIntoNativeMethod()
{
new MockUp<ClassToBeMocked>() {
@Mock
void nativeMethod(Invocation inv)
{
inv.proceed();
fail("Should not get here");
}
};
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage("Cannot proceed");
thrown.expectMessage("native method");
ClassToBeMocked.nativeMethod();
}
@Test
public void proceedFromMockMethodIntoConstructor()
{
new MockUp<ClassToBeMocked>() {
@Mock void $init(Invocation inv)
{
assertNotNull(inv.<ClassToBeMocked>getInvokedInstance());
inv.proceed();
}
};
ClassToBeMocked obj = new ClassToBeMocked();
assertEquals("", obj.name);
}
@Test
public void proceedConditionallyFromMockMethodIntoConstructor()
{
new MockUp<ClassToBeMocked>() {
@Mock void $init(Invocation inv, String name)
{
assertNotNull(inv.getInvokedInstance());
if ("proceed".equals(name)) {
inv.proceed();
}
}
};
assertEquals("proceed", new ClassToBeMocked("proceed").name);
assertNull(new ClassToBeMocked("do not proceed").name);
}
@Test
public void proceedConditionallyFromMockMethodIntoJREConstructor()
{
new MockUp<File>() {
@Mock void $init(Invocation inv, String name)
{
if ("proceed".equals(name)) {
inv.proceed();
}
}
};
assertEquals("proceed", new File("proceed").getPath());
assertNull(new File("do not proceed").getPath());
}
@Test
public void proceedFromMockMethodIntoMethodInheritedFromBaseClass()
{
new MockUp<ClassToBeMocked>() {
@Mock int baseMethod(Invocation inv, int i) { return inv.proceed(i + 1); }
};
assertEquals(3, new ClassToBeMocked().baseMethod(1));
}
}