/* * Copyright (c) 2006 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 org.junit.rules.*; import static org.junit.Assert.*; public final class MisusedExpectationsTest { @Rule public final ExpectedException thrown = ExpectedException.none(); @SuppressWarnings("unused") static class Blah { Blah() {} Blah(int i) {} @SuppressWarnings("RedundantStringConstructorCall") final String name = new String("Blah"); int value() { return -1; } void setValue(int value) {} String doSomething(boolean b) { return ""; } String getName() { return name.toUpperCase(); } Blah same() { return this; } Runnable getSomethingElse() { return null; } static Object doSomething() { return null; } static Object someValue() { return null; } } @Mocked Blah mock; // Arrange-Act-Assert non-conformance ////////////////////////////////////////////////////////////////////////////// @Test public void multipleReplayPhasesWithFirstSetOfExpectationsFullyReplayed() { // First record phase: new StrictExpectations() {{ new Blah().value(); result = 5; }}; // First replay phase: assertEquals(5, new Blah().value()); // Second record phase: new StrictExpectations() {{ mock.value(); result = 6; mock.value(); result = 3; }}; // Second replay phase: assertEquals(6, mock.value()); assertEquals(3, mock.value()); } @Test public void multipleReplayPhasesWithFirstSetOfExpectationsPartiallyReplayed() { // First record phase: new StrictExpectations() {{ mock.value(); returns(1, 2); }}; // First replay phase: assertEquals(1, mock.value()); // Second record phase: new StrictExpectations() {{ mock.value(); returns(3, 4); }}; // Second replay phase: assertEquals(2, mock.value()); assertEquals(3, mock.value()); assertEquals(4, mock.value()); } @Test public void recordNotStrictExpectationAfterInvokingSameMethodInReplayPhase() { assertEquals(0, mock.value()); new Expectations() {{ mock.value(); result = 1; }}; assertEquals(1, mock.value()); } @Test public void recordStrictExpectationAfterInvokingSameMethodInReplayPhase() { assertEquals(0, mock.value()); new StrictExpectations() {{ mock.value(); result = 1; }}; assertEquals(1, mock.value()); } // Duplicate recordings //////////////////////////////////////////////////////////////////////////////////////////// @Test public void recordDuplicateInvocationWithNoArguments() { new Expectations() {{ mock.value(); result = 1; mock.value(); result = 2; // second recording overrides the first }}; assertEquals(2, mock.value()); assertEquals(2, mock.value()); } @Test public void recordDuplicateInvocationWithArgumentMatcher() { new Expectations() {{ mock.setValue(anyInt); result = new UnknownError(); mock.setValue(anyInt); // overrides the previous one }}; mock.setValue(3); } @Test public void recordDuplicateInvocationInSeparateExpectationBlocks() { new Expectations() {{ mock.value(); result = 1; }}; new Expectations() {{ mock.value(); result = 2; }}; // overrides the previous expectation assertEquals(2, mock.value()); } @Test public void recordSameInvocationInNotStrictExpectationBlockThenInStrictOne() { new Expectations() {{ mock.value(); result = 1; }}; new StrictExpectations() {{ mock.value(); result = 2; }}; // overrides previous one assertEquals(2, mock.value()); } // Order-related recordings //////////////////////////////////////////////////////////////////////////////////////// @Test public void recordOrderedInstantiationOfClassMockedTwice(@Mocked Blah mock2) { new StrictExpectations() {{ // OK because of the strictly ordered matching (will match the *first* invocation with this constructor). new Blah(); }}; new Blah(); } @Test public void recordUnorderedInstantiationOfClassMockedTwice(@Mocked final Blah mock2) { new Expectations() {{ new Blah(); times = 1; mock.value(); result = 123; mock2.value(); result = 45; }}; assertEquals(45, mock2.value()); assertEquals(123, mock.value()); new Blah(); } @Test public void verifyOrderedInstantiationOfClassMockedTwice(@Mocked final Blah mock2) { new Blah(); mock2.doSomething(true); new VerificationsInOrder() {{ new Blah(); mock2.doSomething(anyBoolean); }}; } @Test public void verifyUnorderedInstantiationOfClassMockedTwice(@Mocked final Blah mock2) { mock.doSomething(false); mock2.doSomething(true); new Blah(); new Verifications() {{ mock2.doSomething(true); new Blah(); mock.doSomething(false); }}; } // Cascading /////////////////////////////////////////////////////////////////////////////////////////////////////// @Test public void ambiguousCascadingWhenMultipleValidCandidatesAreAvailable( @Injectable Runnable r1, @Injectable Runnable r2) { Runnable cascaded = mock.getSomethingElse(); // which one to return: r1 or r2? assertSame(r2, cascaded); // currently, last mock to be declared wins } // Attempts to mock JRE classes that should never be mocked //////////////////////////////////////////////////////// @Test public void attemptToMockString(@Mocked String s) { assertNotNull(s); } @Test public void attemptToMockStringBuilder(@Mocked StringBuilder s) { assertNotNull(s); } @Test public void attemptToMockStringBuffer(@Mocked StringBuffer s) { assertNotNull(s); } @Test public void attemptToMockArrayList(@Mocked ArrayList<?> list) { assertNotNull(list); } @Test public void attemptToMockLinkedList(@Mocked LinkedList<?> list) { assertNotNull(list); } @Test public void attemptToMockHashMap(@Mocked HashMap<?, ?> map) { assertNotNull(map); } // @Tested/@Injectable usage /////////////////////////////////////////////////////////////////////////////////////// static class TestedClass { Runnable action; } @Injectable static Runnable action = new Runnable() { @Override public void run() {} }; @Tested TestedClass tested; @Test public void checkStaticInjectableIsNotUsed() { assertNull(tested.action); } }