/*
* Copyright (c) 2006 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit;
import java.text.*;
import java.util.*;
import static org.junit.Assert.*;
import org.junit.*;
public final class MockingNewInstancesWithVaryingBehaviorTest
{
static final String DATE_FORMAT = "yyyy-MM-dd";
static final String FORMATTED_DATE = "2012-02-28";
static final String TIME_FORMAT = "HH";
static final String FORMATTED_TIME = "13";
void exerciseAndVerifyTestedCode()
{
Date now = new Date();
String hour = new SimpleDateFormat(TIME_FORMAT).format(now);
assertEquals(FORMATTED_TIME, hour);
String date = new SimpleDateFormat(DATE_FORMAT).format(now);
assertEquals(FORMATTED_DATE, date);
}
/// Tests using the Mockups API ////////////////////////////////////////////////////////////////////////////////////
DateFormat dateFormat;
DateFormat hourFormat;
@Test
public void usingMockUpsWithInvocationParameter()
{
new MockUp<SimpleDateFormat>() {
@Mock
void $init(Invocation inv, String pattern)
{
DateFormat dt = inv.getInvokedInstance();
if (DATE_FORMAT.equals(pattern)) dateFormat = dt;
else if (TIME_FORMAT.equals(pattern)) hourFormat = dt;
}
};
new MockUp<DateFormat>() {
@Mock
String format(Invocation inv, Date d)
{
assertNotNull(d);
DateFormat dt = inv.getInvokedInstance();
if (dt == dateFormat) return FORMATTED_DATE;
else if (dt == hourFormat) return FORMATTED_TIME;
else return null;
}
};
exerciseAndVerifyTestedCode();
}
/// Tests using the Expectations API ///////////////////////////////////////////////////////////////////////////////
@Test // not too complex, but inelegant
public void usingPartialMockingAndDelegate()
{
final SimpleDateFormat sdf = new SimpleDateFormat();
new Expectations(SimpleDateFormat.class) {{
sdf.format((Date) any);
result = new Delegate() {
@Mock String format(Invocation inv)
{
String pattern = inv.<SimpleDateFormat>getInvokedInstance().toPattern();
if (DATE_FORMAT.equals(pattern)) return FORMATTED_DATE;
else if (TIME_FORMAT.equals(pattern)) return FORMATTED_TIME;
else return null;
}
};
}};
exerciseAndVerifyTestedCode();
}
@Test // nice
public void usingReplacementInstances(@Mocked final SimpleDateFormat dateFmt, @Mocked final SimpleDateFormat hourFmt)
{
new Expectations() {{
new SimpleDateFormat(DATE_FORMAT); result = dateFmt;
dateFmt.format((Date) any); result = FORMATTED_DATE;
new SimpleDateFormat(TIME_FORMAT); result = hourFmt;
hourFmt.format((Date) any); result = FORMATTED_TIME;
}};
exerciseAndVerifyTestedCode();
}
@Test // nicer
public void usingInstantiationRecording(@Mocked SimpleDateFormat anyDateFormat)
{
new Expectations() {{
SimpleDateFormat dateFmt = new SimpleDateFormat(DATE_FORMAT);
dateFmt.format((Date) any); result = FORMATTED_DATE;
SimpleDateFormat hourFmt = new SimpleDateFormat(TIME_FORMAT);
hourFmt.format((Date) any); result = FORMATTED_TIME;
}};
exerciseAndVerifyTestedCode();
}
static class Collaborator
{
final int value;
Collaborator() { value = -1; }
Collaborator(int value) { this.value = value; }
Collaborator(String value) { this.value = Integer.parseInt(value); }
int getValue() { return value; }
boolean isPositive() { return value > 0; }
String doSomething(String s) { return s + ": " + value; }
int doSomething(int i) { return i; }
}
@Test
public void matchMethodCallsOnInstancesCreatedWithConstructorMatchingRecordedOne(
@Mocked final Collaborator mock, @Mocked final Collaborator mock5, @Mocked final Collaborator mock6)
{
new Expectations() {{
new Collaborator(5); result = mock5;
mock5.getValue(); result = 123; times = 2;
new Collaborator(); result = mock; times = 1;
new Collaborator(6); result = mock6;
}};
assertEquals(0, new Collaborator().getValue());
Collaborator newCol1 = new Collaborator(5);
assertEquals(123, newCol1.getValue());
Collaborator newCol2 = new Collaborator(6);
assertEquals(0, newCol2.getValue());
assertFalse(newCol2.isPositive());
Collaborator newCol3 = new Collaborator(5);
assertEquals(123, newCol3.getValue());
assertFalse(newCol3.isPositive());
new Verifications() {{
new Collaborator(anyInt); times = 3;
mock.getValue(); times = 1;
mock6.getValue(); times = 1;
mock5.isPositive(); times = 1;
mock6.isPositive(); times = 1;
}};
}
@Test
public void mockInstancesMatchingRecordedConstructorInvocationsToHaveSameBehaviorAsOtherUnmockedInstances()
{
final Collaborator col1 = new Collaborator(1);
final Collaborator col2 = new Collaborator(-2);
new Expectations(Collaborator.class) {{
new Collaborator(3); result = col1;
new Collaborator(5); result = col2;
col1.doSomething("recorded"); result = "mocked";
}};
Collaborator newCol1 = new Collaborator(-10);
assertEquals(-10, newCol1.getValue());
assertEquals("not mocked: -10", newCol1.doSomething("not mocked"));
assertEquals("recorded: -10", newCol1.doSomething("recorded"));
Collaborator newCol2 = new Collaborator(3);
assertEquals(1, newCol2.getValue());
assertEquals("mocked", newCol2.doSomething("recorded"));
assertEquals("not recorded: 1", newCol2.doSomething("not recorded"));
Collaborator newCol3 = new Collaborator(5);
assertEquals(-2, newCol3.getValue());
assertFalse(newCol3.isPositive());
assertEquals("null: -2", newCol3.doSomething(null));
Collaborator newCol4 = new Collaborator(10);
assertEquals(10, newCol4.getValue());
assertTrue(newCol4.isPositive());
Collaborator newCol5 = new Collaborator(3);
assertEquals(1, newCol5.getValue());
assertTrue(newCol5.isPositive());
assertEquals("mocked", newCol5.doSomething("recorded"));
assertEquals("test: 1", newCol5.doSomething("test"));
new Verifications() {{
col1.getValue(); times = 2;
col1.isPositive(); times = 1;
col2.getValue(); times = 1;
col2.isPositive(); times = 1;
col1.doSomething(anyString); times = 4;
col2.doSomething(anyString); times = 1;
}};
}
@Test
public void recordDifferentResultsForInstancesCreatedWithDifferentConstructors(@Mocked final Collaborator anyCol)
{
new Expectations() {{
anyCol.getValue(); result = 1;
Collaborator col2 = new Collaborator(anyInt);
col2.getValue(); result = 2;
}};
int valueFromRecordedConstructor = new Collaborator(10).getValue();
int valueFromAnyOtherConstructor = new Collaborator().getValue();
assertEquals(2, valueFromRecordedConstructor);
assertEquals(1, valueFromAnyOtherConstructor);
}
}