/*
* 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.nio.*;
import javax.annotation.*;
import org.junit.*;
import org.junit.runners.*;
import static org.junit.Assert.*;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public final class MockingUpBaseTypesTest
{
static class BeforeClassBaseAction { protected int perform() { return -1; } }
static class BeforeClassAction extends BeforeClassBaseAction { @Override protected int perform() { return 12; } }
@BeforeClass
public static <T extends BeforeClassBaseAction> void applyMockUpForAllTests()
{
new MockUp<T>() {
@Mock int perform() { return 34; }
};
}
@AfterClass
public static void verifyMockUpForAllTestsIsInEffect()
{
int i1 = new BeforeClassAction().perform();
int i2 = new BeforeClassBaseAction().perform();
assertEquals(34, i1);
assertEquals(34, i2);
}
public interface IBeforeAction { @SuppressWarnings("unused") int perform(); }
static class BeforeAction implements IBeforeAction { @Override public int perform() { return 123; } }
@Before
public <T extends IBeforeAction> void applyMockUpForEachTest()
{
new MockUp<T>() {
@Mock int perform() { return 56; }
};
}
@After
public void verifyMockUpForEachTestIsInEffect()
{
int i = new BeforeAction().perform();
assertEquals(56, i);
}
public interface IAction
{
int perform(int i);
boolean notToBeMocked();
}
public static class ActionImpl1 implements IAction
{
@Override public int perform(int i) { return i - 1; }
@Override public boolean notToBeMocked() { return true; }
}
static final class ActionImpl2 implements IAction
{
@Override public int perform(int i) { return i - 2; }
@Override public boolean notToBeMocked() { return true; }
}
IAction actionI;
@Test
public <T extends IAction> void test3_mockUpInterfaceImplementationClassesUsingAnonymousMockUp()
{
actionI = new ActionImpl1();
new MockUp<T>() {
@Mock
int perform(int i) { return i + 1; }
};
assertEquals(2, actionI.perform(1));
assertTrue(actionI.notToBeMocked());
ActionImpl2 impl2 = new ActionImpl2();
assertEquals(3, impl2.perform(2));
assertTrue(impl2.notToBeMocked());
}
public interface TestInterface { String getData(); }
public static final class MockTestInterface<T extends TestInterface> extends MockUp<T>
{
@Mock
public String getData(Invocation inv) { return "mocked" + inv.proceed(); }
}
@Test
public void mockAllClassesImplementingAnInterfaceUsingNamedMockUpWithInvocationParameter()
{
TestInterface impl1 = new TestInterface() { @Override public String getData() { return "1"; } };
TestInterface impl2 = new TestInterface() { @Override public String getData() { return "2"; } };
new MockTestInterface();
String mocked1 = impl1.getData();
String mocked2 = impl2.getData();
assertEquals("mocked1", mocked1);
assertEquals("mocked2", mocked2);
}
public abstract static class BaseAction
{
protected abstract int perform(int i);
public int toBeMockedAsWell() { return -1; }
int notToBeMocked() { return 1; }
}
static final class ConcreteAction1 extends BaseAction
{
@Override public int perform(int i) { return i - 1; }
}
static class ConcreteAction2 extends BaseAction
{
@Override protected int perform(int i) { return i - 2; }
@Override public int toBeMockedAsWell() { return super.toBeMockedAsWell() - 1; }
@Override int notToBeMocked() { return super.notToBeMocked() + 1; }
}
static class ConcreteAction3 extends ConcreteAction2
{
@Override public int perform(int i) { return i - 3; }
@Override public int toBeMockedAsWell() { return -3; }
@Override final int notToBeMocked() { return 3; }
}
BaseAction actionB;
@Test
public <T extends BaseAction> void test4_mockUpConcreteSubclassesUsingAnonymousMockUp()
{
actionB = new ConcreteAction1();
new MockUp<T>() {
@Mock int perform(int i) { return i + 1; }
@Mock int toBeMockedAsWell() { return 123; }
};
assertEquals(2, actionB.perform(1));
assertEquals(123, actionB.toBeMockedAsWell());
assertEquals(1, actionB.notToBeMocked());
ConcreteAction2 action2 = new ConcreteAction2();
assertEquals(3, action2.perform(2));
assertEquals(123, action2.toBeMockedAsWell());
assertEquals(2, action2.notToBeMocked());
ConcreteAction3 action3 = new ConcreteAction3();
assertEquals(4, action3.perform(3));
assertEquals(123, action3.toBeMockedAsWell());
assertEquals(3, action3.notToBeMocked());
}
@After
public void checkImplementationClassesAreNoLongerMocked()
{
if (actionI != null) {
assertEquals(-1, actionI.perform(0));
}
assertEquals(-2, new ActionImpl2().perform(0));
if (actionB != null) {
assertEquals(-1, actionB.perform(0));
}
assertEquals(-2, new ConcreteAction2().perform(0));
assertEquals(-3, new ConcreteAction3().perform(0));
}
static final class InterfaceMockUp<T extends IAction> extends MockUp<T>
{
@Mock
int perform(int i) { return i + 2; }
}
@Test
public void test5_mockUpInterfaceImplementationClassesUsingNamedMockUp()
{
new InterfaceMockUp();
actionI = new ActionImpl1();
assertEquals(3, actionI.perform(1));
assertEquals(4, new ActionImpl2().perform(2));
}
static final class BaseClassMockUp<T extends BaseAction> extends MockUp<T>
{
@Mock
int perform(int i) { return i + 3; }
}
@Test
public void test6_mockUpConcreteSubclassesUsingNamedMockUp()
{
new BaseClassMockUp();
actionB = new ConcreteAction1();
assertEquals(4, actionB.perform(1));
assertEquals(5, new ConcreteAction2().perform(2));
assertEquals(6, new ConcreteAction3().perform(3));
}
interface GenericIAction<N extends Number> { N perform(N n); }
@Test
public <M extends GenericIAction<Number>> void test7_mockUpImplementationsOfGenericInterface()
{
GenericIAction<Number> actionNumber = new GenericIAction<Number>() {
@Override public Number perform(Number n) { return n.intValue() + 1; }
};
GenericIAction<Integer> actionInt = new GenericIAction<Integer>() {
@Override public Integer perform(Integer n) { return n + 1; }
};
GenericIAction<Long> actionL = new GenericIAction<Long>() {
@Override public Long perform(Long n) { return n + 2; }
};
new MockUp<M>() {
@Mock Number perform(Number n) { return n.intValue() - 1; }
};
Number n = actionNumber.perform(1);
assertEquals(0, n); // mocked
int i = actionInt.perform(2);
assertEquals(3, i); // not mocked
long l = actionL.perform(3L);
assertEquals(5, l); // not mocked
}
@Test
public <R extends Readable> void test8_excludeJREClassesFromMockingForSafety() throws Exception
{
new MockUp<R>() {
@Mock
int read(CharBuffer cb) { return 123; }
};
CharBuffer buf = CharBuffer.allocate(10);
int r1 = new Readable() { @Override public int read(@Nonnull CharBuffer cb) { return 1; } }.read(buf);
assertEquals(123, r1);
int r2 = new StringReader("test").read(buf);
assertEquals(4, r2);
}
}