1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.internal.stubbing;
6 
7 import org.junit.Test;
8 import org.mockito.internal.creation.MockSettingsImpl;
9 import org.mockito.internal.invocation.InvocationBuilder;
10 import org.mockito.internal.invocation.InvocationMatcher;
11 import org.mockito.internal.stubbing.answers.Returns;
12 import org.mockito.internal.stubbing.defaultanswers.ReturnsEmptyValues;
13 import org.mockito.invocation.Invocation;
14 import org.mockito.mock.MockCreationSettings;
15 
16 import java.util.LinkedList;
17 import java.util.concurrent.CountDownLatch;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 
23 /**
24  * Author: Szczepan Faber
25  */
26 public class InvocationContainerImplTest {
27 
28     InvocationContainerImpl container = new InvocationContainerImpl( new MockSettingsImpl());
29     InvocationContainerImpl containerStubOnly =
30       new InvocationContainerImpl( (MockCreationSettings) new MockSettingsImpl().stubOnly());
31     Invocation invocation = new InvocationBuilder().toInvocation();
32     LinkedList<Throwable> exceptions = new LinkedList<Throwable>();
33 
34     @Test
should_be_thread_safe()35     public void should_be_thread_safe() throws Throwable {
36         doShouldBeThreadSafe(container);
37     }
38 
39     @Test
should_be_thread_safe_stub_only()40     public void should_be_thread_safe_stub_only() throws Throwable {
41         doShouldBeThreadSafe(containerStubOnly);
42     }
43 
44     //works 50% of the time
doShouldBeThreadSafe(final InvocationContainerImpl c)45     private void doShouldBeThreadSafe(final InvocationContainerImpl c) throws Throwable {
46         //given
47         Thread[] t = new Thread[200];
48         final CountDownLatch starter = new CountDownLatch(200);
49         for (int i = 0; i < t.length; i++ ) {
50             t[i] = new Thread() {
51                 public void run() {
52                     try {
53                         starter.await(); //NOPMD
54                     } catch (InterruptedException e) {
55                         throw new RuntimeException(e);
56                     }
57                     c.setInvocationForPotentialStubbing(new InvocationMatcher(invocation));
58                     c.addAnswer(new Returns("foo"), null);
59                     c.findAnswerFor(invocation);
60                 }
61             };
62             t[i].setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
63                 public void uncaughtException(Thread t, Throwable e) {
64                     exceptions.add(e);
65                 }
66             });
67             t[i].start();
68 
69             starter.countDown();
70         }
71 
72         //when
73         for (Thread aT : t) {
74             aT.join();
75         }
76 
77         //then
78         if (exceptions.size() != 0) {
79             throw exceptions.getFirst();
80         }
81     }
82 
83     @Test
should_return_invoked_mock()84     public void should_return_invoked_mock() throws Exception {
85         container.setInvocationForPotentialStubbing(new InvocationMatcher(invocation));
86 
87         assertEquals(invocation.getMock(), container.invokedMock());
88     }
89 
90     @Test
should_return_invoked_mock_stub_only()91     public void should_return_invoked_mock_stub_only() throws Exception {
92         containerStubOnly.setInvocationForPotentialStubbing(new InvocationMatcher(invocation));
93 
94         assertEquals(invocation.getMock(), containerStubOnly.invokedMock());
95     }
96 
97     @Test
should_tell_if_has_invocation_for_potential_stubbing()98     public void should_tell_if_has_invocation_for_potential_stubbing() throws Exception {
99         container.setInvocationForPotentialStubbing(new InvocationBuilder().toInvocationMatcher());
100         assertTrue(container.hasInvocationForPotentialStubbing());
101 
102         container.addAnswer(new ReturnsEmptyValues(), null);
103         assertFalse(container.hasInvocationForPotentialStubbing());
104     }
105 
106     @Test
should_tell_if_has_invocation_for_potential_stubbing_stub_only()107     public void should_tell_if_has_invocation_for_potential_stubbing_stub_only() throws Exception {
108         containerStubOnly.setInvocationForPotentialStubbing(new InvocationBuilder().toInvocationMatcher());
109         assertTrue(containerStubOnly.hasInvocationForPotentialStubbing());
110 
111         containerStubOnly.addAnswer(new ReturnsEmptyValues(), null);
112         assertFalse(containerStubOnly.hasInvocationForPotentialStubbing());
113     }
114 }
115