/*
* Copyright (c) 2006 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit;
import java.nio.*;
import java.util.*;
import java.util.concurrent.*;
import org.junit.*;
import static org.junit.Assert.*;
public final class CapturingInstancesTest
{
public interface Service1 { int doSomething(); }
static final class Service1Impl implements Service1 { @Override public int doSomething() { return 1; } }
public static final class TestedUnit
{
private final Service1 service1 = new Service1Impl();
private final Service1 service2 = new Service1() { @Override public int doSomething() { return 2; } };
Observable observable;
public int businessOperation(final boolean b)
{
new Callable() {
@Override public Object call() { throw new IllegalStateException(); }
}.call();
observable = new Observable() {{
if (b) {
throw new IllegalArgumentException();
}
}};
return service1.doSomething() + service2.doSomething();
}
}
@Capturing(maxInstances = 2) Service1 service;
@Test
public void captureServiceInstancesCreatedByTestedConstructor()
{
TestedUnit unit = new TestedUnit();
assertEquals(0, unit.service1.doSomething());
assertEquals(0, unit.service2.doSomething());
}
@Test
public void captureAllInternallyCreatedInstances(
@Capturing Observable observable, @Capturing final Callable<?> callable) throws Exception
{
new Expectations() {{
service.doSomething(); returns(3, 4);
}};
TestedUnit unit = new TestedUnit();
int result = unit.businessOperation(true);
assertEquals(4, unit.service1.doSomething());
assertEquals(4, unit.service2.doSomething());
assertNotNull(unit.observable);
assertEquals(7, result);
new Verifications() {{ callable.call(); }};
}
public interface Service2 { int doSomething(); }
static final class Service2Impl implements Service2 { @Override public int doSomething() { return 2; } }
@Test
public void recordStrictExpectationsForNextTwoInstancesToBeCreated(
@Capturing(maxInstances = 1) final Service2 s1, @Capturing(maxInstances = 1) final Service2 s2)
{
new StrictExpectations() {{
s1.doSomething(); result = 11;
s2.doSomething(); returns(22, 33);
}};
assertEquals(11, new Service2Impl().doSomething());
Service2Impl s = new Service2Impl();
assertEquals(22, s.doSomething());
assertEquals(33, s.doSomething());
}
@Test
public void recordExpectationsForNextTwoInstancesToBeCreated(
@Capturing(maxInstances = 1) final Service2 mock1, @Capturing(maxInstances = 1) final Service2 mock2)
{
new Expectations() {{
mock1.doSomething(); result = 11;
mock2.doSomething(); result = 22;
}};
Service2Impl s1 = new Service2Impl();
Service2Impl s2 = new Service2Impl();
assertEquals(22, s2.doSomething());
assertEquals(11, s1.doSomething());
assertEquals(11, s1.doSomething());
assertEquals(22, s2.doSomething());
assertEquals(11, s1.doSomething());
}
@Test
public void recordExpectationsForNextTwoInstancesOfTwoDifferentImplementingClasses(
@Capturing(maxInstances = 1) final Service2 mock1, @Capturing(maxInstances = 1) final Service2 mock2)
{
new Expectations() {{
mock1.doSomething(); result = 1;
mock2.doSomething(); result = 2;
}};
Service2 s1 = new Service2() { @Override public int doSomething() { return -1; } };
assertEquals(1, s1.doSomething());
Service2 s2 = new Service2() { @Override public int doSomething() { return -2; } };
assertEquals(2, s2.doSomething());
}
@Test
public void recordExpectationsForTwoConsecutiveSetsOfFutureInstances(
@Capturing(maxInstances = 2) final Service2 set1, @Capturing(maxInstances = 3) final Service2 set2)
{
new Expectations() {{
set1.doSomething(); result = 1;
set2.doSomething(); result = 2;
}};
// First set of instances, matching the expectation on "s1":
Service2 s1 = new Service2Impl();
Service2 s2 = new Service2Impl();
assertEquals(1, s1.doSomething());
assertEquals(1, s2.doSomething());
// Second set of instances, matching the expectation on "s2":
Service2 s3 = new Service2Impl();
Service2 s4 = new Service2Impl();
Service2 s5 = new Service2Impl();
assertEquals(2, s3.doSomething());
assertEquals(2, s4.doSomething());
assertEquals(2, s5.doSomething());
// Third set of instances, not matching any expectation:
Service2 s6 = new Service2Impl();
assertEquals(0, s6.doSomething());
}
@Test
public void recordExpectationsForNextTwoInstancesToBeCreatedUsingMockParameters(
@Capturing(maxInstances = 1) final Service2 s1, @Capturing(maxInstances = 1) final Service2 s2)
{
new Expectations() {{
s2.doSomething(); result = 22;
s1.doSomething(); result = 11;
}};
Service2Impl cs1 = new Service2Impl();
assertEquals(11, cs1.doSomething());
Service2Impl cs2 = new Service2Impl();
assertEquals(22, cs2.doSomething());
assertEquals(11, cs1.doSomething());
assertEquals(22, cs2.doSomething());
}
static class Base { boolean doSomething() { return false; } }
static final class Derived1 extends Base {}
static final class Derived2 extends Base { Service2 doSomethingElse() { return null; } }
@Test
public void verifyExpectationsOnlyOnFirstOfTwoCapturedInstances(@Capturing(maxInstances = 1) final Base b)
{
new Expectations() {{
b.doSomething(); result = true; times = 1;
}};
assertTrue(new Derived1().doSomething());
assertFalse(new Derived2().doSomething());
}
@Test
public void verifyExpectationsOnlyOnOneOfTwoSubclassesForTwoCapturedInstances(
@Capturing(maxInstances = 1) final Derived1 firstCapture,
@Capturing(maxInstances = 1) final Derived1 secondCapture)
{
new Expectations() {{
new Derived1(); times = 2;
firstCapture.doSomething(); result = true; times = 1;
secondCapture.doSomething(); result = true; times = 1;
}};
assertTrue(new Derived1().doSomething());
assertFalse(new Derived2().doSomething());
assertTrue(new Derived1().doSomething());
}
@Test
public void captureSubclassAndCascadeFromMethodExclusiveToSubclass(@Capturing Base capturingMock)
{
Derived2 d = new Derived2();
Service2 service2 = d.doSomethingElse();
// Classes mocked only because they implement/extend a capturing base type do not cascade from methods
// that exist only in them.
//noinspection ConstantConditions
assertNull(service2);
}
@Test
public void specifyDifferentBehaviorForFirstNewInstanceAndForRemainingNewInstances(
@Capturing(maxInstances = 1) final Buffer firstNewBuffer, @Capturing final Buffer remainingNewBuffers)
{
new Expectations() {{
firstNewBuffer.position(); result = 10;
remainingNewBuffers.position(); result = 20;
}};
ByteBuffer buffer1 = ByteBuffer.allocate(100);
IntBuffer buffer2 = IntBuffer.wrap(new int[] {1, 2, 3});
CharBuffer buffer3 = CharBuffer.wrap(" ");
assertEquals(10, buffer1.position());
assertEquals(20, buffer2.position());
assertEquals(20, buffer3.position());
}
}