/*
* 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 org.junit.Assert.*;
@SuppressWarnings({"UnusedDeclaration"})
public final class DelegateInvocationTest
{
static class Collaborator
{
Collaborator() {}
Collaborator(int i) {}
int getValue() { return -1; }
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 float privateMethod() { return 1.2F; }
void addElements(Collection<String> elements) { elements.add("one element"); }
}
@Test
public void delegateWithContextObject()
{
new NonStrictExpectations()
{
final Collaborator unused = null;
{
Collaborator.staticMethod();
returns(new Delegate()
{
boolean staticMethod(Invocation context)
{
assertNull(context.getInvokedInstance());
assertEquals(context.getInvocationCount() - 1, context.getInvocationIndex());
return context.getInvocationCount() > 0;
}
});
}
};
assertTrue(Collaborator.staticMethod());
assertTrue(Collaborator.staticMethod());
}
static class ConstructorDelegate implements Delegate
{
int capturedArgument;
void $init(Invocation context, int i)
{
assertNotNull(context.getInvokedInstance());
capturedArgument = i + context.getInvocationCount();
}
}
@Test
public void delegateForConstructorWithContext()
{
final ConstructorDelegate delegate = new ConstructorDelegate();
new Expectations()
{
Collaborator mock;
{
new Collaborator(anyInt); result = delegate;
}
};
new Collaborator(4);
assertEquals(5, delegate.capturedArgument);
}
@Test
public void delegateReceivingNullArguments()
{
final Collaborator collaborator = new Collaborator();
new NonStrictExpectations()
{
Collaborator mock;
{
mock.doSomething(true, null, null);
result = new Delegate()
{
void doSomething(Invocation invocation, Boolean b, int[] i, String s)
{
Collaborator instance = invocation.getInvokedInstance();
assertSame(collaborator, instance);
assertEquals(1, invocation.getInvocationCount());
assertTrue(b);
assertNull(i);
assertNull(s);
}
};
}
};
assertNull(collaborator.doSomething(true, null, null));
}
@Test
public void delegateWithAnotherMethodOnTheDelegateClass()
{
new NonStrictExpectations()
{
Collaborator mock;
{
mock.getValue();
result = new Delegate()
{
int getValue(Invocation context)
{
return context.getInvocationCount();
}
void otherMethod(Invocation context)
{
fail();
}
};
}
};
assertEquals(1, new Collaborator().getValue());
assertEquals(2, new Collaborator().getValue());
}
@Test
public void delegateClassWithMultipleMethodsAndInexactButValidMatch()
{
new NonStrictExpectations()
{
Collaborator mock;
{
Collaborator.staticMethod(1);
result = new Delegate()
{
void otherMethod(int i)
{
fail();
}
boolean staticMethod(Invocation invocation, Number i)
{
return i.intValue() > 0;
}
};
}
};
assertTrue(Collaborator.staticMethod(1));
}
@Test
public void delegateOverridingInvocationCountConstraints(final Collaborator mock)
{
new NonStrictExpectations()
{
{
mock.finalMethod(); maxTimes = 1;
result = new Delegate()
{
char finalMethod(Invocation invocation)
{
invocation.setMinInvocations(2);
invocation.setMaxInvocations(2);
return 'a';
}
};
}
};
assertEquals('a', mock.finalMethod());
assertEquals('a', mock.finalMethod());
}
@Test(expected = IllegalArgumentException.class)
public void delegateClassWithNoMethodMatchingTheExpectationSignature(final Collaborator mock)
{
new Expectations()
{
{
mock.privateMethod();
result = new Delegate()
{
float someDelegate(Invocation invocation) { return 1.0F; }
void someOtherMethod() {}
};
}
};
assertEquals(1.0, mock.privateMethod(), 0.0);
}
@Test
public void delegateWithDifferentMethodName()
{
new NonStrictExpectations()
{
Collaborator mock;
{
mock.nativeMethod(anyBoolean);
result = new Delegate()
{
long differentName(Invocation invocation, boolean b)
{
assertEquals(1, invocation.getInvocationCount());
assertTrue(b);
return 3L;
}
};
}
};
assertEquals(3L, new Collaborator().nativeMethod(true));
}
@Test
public void delegatesForTwoSeparateExpectations(final Collaborator mock)
{
new Expectations()
{
{
//noinspection unchecked
mock.addElements((Collection<String>) any);
forEachInvocation = new Object()
{
void delegate1(Invocation invocation, Collection<String> elements)
{
assertSame(mock, invocation.getInvokedInstance());
assertEquals(1, invocation.getInvocationCount());
assertNotNull(elements);
}
};
mock.addElements(null);
forEachInvocation = new Object()
{
void delegate2(Invocation invocation, Collection<String> elements)
{
assertSame(mock, invocation.getInvokedInstance());
assertEquals(1, invocation.getInvocationCount());
assertNull(elements);
}
};
}
};
mock.addElements(Collections.<String>emptyList());
mock.addElements(null);
}
@Test
public void consecutiveDelegatesForTheSameExpectation(final Collaborator mock)
{
new Expectations()
{
{
mock.getValue();
returns(
new Delegate()
{
int delegate(Invocation invocation)
{
return invocation.getInvocationCount();
}
},
new Delegate()
{
int delegate(Invocation invocation)
{
return invocation.getInvocationCount();
}
},
new Delegate()
{
int delegate(Invocation invocation)
{
assertEquals(3, invocation.getInvocationCount());
throw new SecurityException();
}
});
}
};
assertEquals(1, mock.getValue());
assertEquals(2, mock.getValue());
try {
mock.getValue();
fail();
}
catch (SecurityException e) {
// OK
}
}
}