• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockitoinline;
6 
7 import static junit.framework.TestCase.assertEquals;
8 import static junit.framework.TestCase.assertNull;
9 import static junit.framework.TestCase.assertTrue;
10 import static org.assertj.core.api.Assertions.assertThatThrownBy;
11 import static org.mockito.Mockito.times;
12 import static org.mockito.Mockito.verify;
13 import static org.mockito.Mockito.when;
14 
15 import java.util.Collections;
16 import java.util.concurrent.atomic.AtomicReference;
17 
18 import org.junit.Test;
19 import org.mockito.MockedConstruction;
20 import org.mockito.Mockito;
21 import org.mockito.exceptions.base.MockitoException;
22 
23 public final class ConstructionMockTest {
24 
25     @Test
testConstructionMockSimple()26     public void testConstructionMockSimple() {
27         assertEquals("foo", new Dummy().foo());
28         try (MockedConstruction<Dummy> ignored = Mockito.mockConstruction(Dummy.class)) {
29             assertNull(new Dummy().foo());
30         }
31         assertEquals("foo", new Dummy().foo());
32     }
33 
34     @Test
testConstructionMockCollection()35     public void testConstructionMockCollection() {
36         try (MockedConstruction<Dummy> dummy = Mockito.mockConstruction(Dummy.class)) {
37             assertEquals(0, dummy.constructed().size());
38             Dummy mock = new Dummy();
39             assertEquals(1, dummy.constructed().size());
40             assertTrue(dummy.constructed().contains(mock));
41         }
42     }
43 
44     @Test
testConstructionMockDefaultAnswer()45     public void testConstructionMockDefaultAnswer() {
46         try (MockedConstruction<Dummy> ignored = Mockito.mockConstructionWithAnswer(Dummy.class, invocation -> "bar")) {
47             assertEquals("bar", new Dummy().foo());
48         }
49     }
50 
51     @Test
testConstructionMockDefaultAnswerMultiple()52     public void testConstructionMockDefaultAnswerMultiple() {
53         try (MockedConstruction<Dummy> ignored = Mockito.mockConstructionWithAnswer(Dummy.class, invocation -> "bar", invocation -> "qux")) {
54             assertEquals("bar", new Dummy().foo());
55             assertEquals("qux", new Dummy().foo());
56             assertEquals("qux", new Dummy().foo());
57         }
58     }
59 
60     /**
61      * Tests issue #2544
62      */
63     @Test
testConstructionMockDefaultAnswerMultipleMoreThanTwo()64     public void testConstructionMockDefaultAnswerMultipleMoreThanTwo() {
65         try (MockedConstruction<Dummy> ignored = Mockito.mockConstructionWithAnswer(Dummy.class, invocation -> "bar", invocation -> "qux", invocation -> "baz")) {
66             assertEquals("bar", new Dummy().foo());
67             assertEquals("qux", new Dummy().foo());
68             assertEquals("baz", new Dummy().foo());
69             assertEquals("baz", new Dummy().foo());
70         }
71     }
72 
73     @Test
testConstructionMockPrepared()74     public void testConstructionMockPrepared() {
75         try (MockedConstruction<Dummy> ignored = Mockito.mockConstruction(Dummy.class, (mock, context) -> when(mock.foo()).thenReturn("bar"))) {
76             assertEquals("bar", new Dummy().foo());
77         }
78     }
79 
80 
81     @Test
testConstructionMockContext()82     public void testConstructionMockContext() {
83         try (MockedConstruction<Dummy> ignored = Mockito.mockConstruction(Dummy.class, (mock, context) -> {
84             assertEquals(1, context.getCount());
85             assertEquals(Collections.singletonList("foobar"), context.arguments());
86             assertEquals(mock.getClass().getDeclaredConstructor(String.class), context.constructor());
87             when(mock.foo()).thenReturn("bar");
88         })) {
89             assertEquals("bar", new Dummy("foobar").foo());
90         }
91     }
92 
93     @Test
testConstructionMockDoesNotAffectDifferentThread()94     public void testConstructionMockDoesNotAffectDifferentThread() throws InterruptedException {
95         try (MockedConstruction<Dummy> ignored = Mockito.mockConstruction(Dummy.class)) {
96             Dummy dummy = new Dummy();
97             when(dummy.foo()).thenReturn("bar");
98             assertEquals("bar", dummy.foo());
99             verify(dummy).foo();
100             AtomicReference<String> reference = new AtomicReference<>();
101             Thread thread = new Thread(() -> reference.set(new Dummy().foo()));
102             thread.start();
103             thread.join();
104             assertEquals("foo", reference.get());
105             when(dummy.foo()).thenReturn("bar");
106             assertEquals("bar", dummy.foo());
107             verify(dummy, times(2)).foo();
108         }
109     }
110 
111     @Test
testConstructionMockCanCoexistWithMockInDifferentThread()112     public void testConstructionMockCanCoexistWithMockInDifferentThread() throws InterruptedException {
113         try (MockedConstruction<Dummy> ignored = Mockito.mockConstruction(Dummy.class)) {
114             Dummy dummy = new Dummy();
115             when(dummy.foo()).thenReturn("bar");
116             assertEquals("bar", dummy.foo());
117             verify(dummy).foo();
118             AtomicReference<String> reference = new AtomicReference<>();
119             Thread thread = new Thread(() -> {
120                 try (MockedConstruction<Dummy> ignored2 = Mockito.mockConstruction(Dummy.class)) {
121                     Dummy other = new Dummy();
122                     when(other.foo()).thenReturn("qux");
123                     reference.set(other.foo());
124                 }
125             });
126             thread.start();
127             thread.join();
128             assertEquals("qux", reference.get());
129             assertEquals("bar", dummy.foo());
130             verify(dummy, times(2)).foo();
131         }
132     }
133 
134     @Test
testConstructionMockMustBeExclusiveInScopeWithinThread()135     public void testConstructionMockMustBeExclusiveInScopeWithinThread() {
136         assertThatThrownBy(
137                 () -> {
138                     try (
139                             MockedConstruction<Dummy> dummy = Mockito.mockConstruction(Dummy.class);
140                             MockedConstruction<Dummy> duplicate = Mockito.mockConstruction(Dummy.class)) {
141                     }
142                 })
143                 .isInstanceOf(MockitoException.class)
144                 .hasMessageContaining("static mocking is already registered in the current thread");
145     }
146 
147     @Test
testConstructionMockMustNotTargetAbstractClass()148     public void testConstructionMockMustNotTargetAbstractClass() {
149         assertThatThrownBy(
150                 () -> {
151                     Mockito.mockConstruction(Runnable.class).close();
152                 })
153                 .isInstanceOf(MockitoException.class)
154                 .hasMessageContaining("It is not possible to construct primitive types or abstract types");
155     }
156 
157     static class Dummy {
158 
159 
Dummy()160         public Dummy() {
161         }
162 
Dummy(String value)163         public Dummy(String value) {
164         }
165 
foo()166         String foo() {
167             return "foo";
168         }
169     }
170 }
171