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 org.assertj.core.api.Assertions.assertThatThrownBy; 10 import static org.mockito.ArgumentMatchers.any; 11 import static org.mockito.Mockito.times; 12 13 import java.util.concurrent.atomic.AtomicReference; 14 15 import org.junit.Test; 16 import org.mockito.MockedStatic; 17 import org.mockito.Mockito; 18 import org.mockito.exceptions.base.MockitoException; 19 import org.mockito.exceptions.verification.NoInteractionsWanted; 20 import org.mockito.exceptions.verification.WantedButNotInvoked; 21 22 public final class StaticMockTest { 23 24 @Test testStaticMockSimple()25 public void testStaticMockSimple() { 26 assertEquals("foo", Dummy.foo()); 27 try (MockedStatic<Dummy> ignored = Mockito.mockStatic(Dummy.class)) { 28 assertNull(Dummy.foo()); 29 } 30 assertEquals("foo", Dummy.foo()); 31 } 32 33 @Test testStaticMockWithVerification()34 public void testStaticMockWithVerification() { 35 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 36 dummy.when(Dummy::foo).thenReturn("bar"); 37 assertEquals("bar", Dummy.foo()); 38 dummy.verify(Dummy::foo); 39 } 40 } 41 42 @Test testStaticMockWithVerificationFailed()43 public void testStaticMockWithVerificationFailed() { 44 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 45 assertThatThrownBy( 46 () -> { 47 dummy.verify(Dummy::foo); 48 }) 49 .isInstanceOf(WantedButNotInvoked.class) 50 .hasMessageContaining("there were zero interactions with this mock"); 51 } 52 } 53 54 @Test testStaticMockWithNoInteractions()55 public void testStaticMockWithNoInteractions() { 56 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 57 dummy.when(Dummy::foo).thenReturn("bar"); 58 dummy.verifyNoInteractions(); 59 } 60 } 61 62 @Test testStaticMockWithNoInteractionsFailed()63 public void testStaticMockWithNoInteractionsFailed() { 64 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 65 dummy.when(Dummy::foo).thenReturn("bar"); 66 assertEquals("bar", Dummy.foo()); 67 assertThatThrownBy( 68 () -> { 69 dummy.verifyNoInteractions(); 70 }) 71 .isInstanceOf(NoInteractionsWanted.class) 72 .hasMessageContaining("No interactions wanted here") 73 .hasMessageContaining("above is the only interaction with this mock."); 74 } 75 } 76 77 @Test testStaticMockWithNoMoreInteractions()78 public void testStaticMockWithNoMoreInteractions() { 79 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 80 dummy.when(Dummy::foo).thenReturn("bar"); 81 assertEquals("bar", Dummy.foo()); 82 dummy.verify(Dummy::foo); 83 dummy.verifyNoMoreInteractions(); 84 } 85 } 86 87 @Test testStaticMockWithNoMoreInteractionsFailed()88 public void testStaticMockWithNoMoreInteractionsFailed() { 89 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 90 dummy.when(Dummy::foo).thenReturn("bar"); 91 assertEquals("bar", Dummy.foo()); 92 assertThatThrownBy( 93 () -> { 94 dummy.verifyNoInteractions(); 95 }) 96 .isInstanceOf(NoInteractionsWanted.class) 97 .hasMessageContaining("No interactions wanted here") 98 .hasMessageContaining("above is the only interaction with this mock."); 99 } 100 } 101 102 @Test testStaticMockWithDefaultAnswer()103 public void testStaticMockWithDefaultAnswer() { 104 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class, invocation -> "bar")) { 105 assertEquals("bar", Dummy.foo()); 106 dummy.verify(Dummy::foo); 107 } 108 } 109 110 @Test testStaticMockWithRealMethodCall()111 public void testStaticMockWithRealMethodCall() { 112 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 113 dummy.when(Dummy::foo).thenCallRealMethod(); 114 assertEquals("foo", Dummy.foo()); 115 dummy.verify(Dummy::foo); 116 } 117 } 118 119 @Test testStaticMockReset()120 public void testStaticMockReset() { 121 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 122 dummy.when(Dummy::foo).thenReturn("bar"); 123 dummy.reset(); 124 assertNull(Dummy.foo()); 125 } 126 } 127 128 @Test testStaticMockClear()129 public void testStaticMockClear() { 130 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 131 dummy.when(Dummy::foo).thenReturn("bar"); 132 assertEquals("bar", Dummy.foo()); 133 dummy.clearInvocations(); 134 dummy.verifyNoInteractions(); 135 } 136 } 137 138 @Test testStaticMockDoesNotAffectDifferentThread()139 public void testStaticMockDoesNotAffectDifferentThread() throws InterruptedException { 140 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 141 dummy.when(Dummy::foo).thenReturn("bar"); 142 assertEquals("bar", Dummy.foo()); 143 dummy.verify(Dummy::foo); 144 AtomicReference<String> reference = new AtomicReference<>(); 145 Thread thread = new Thread(() -> reference.set(Dummy.foo())); 146 thread.start(); 147 thread.join(); 148 assertEquals("foo", reference.get()); 149 dummy.when(Dummy::foo).thenReturn("bar"); 150 assertEquals("bar", Dummy.foo()); 151 dummy.verify(Dummy::foo, times(2)); 152 } 153 } 154 155 @Test testStaticMockCanCoexistWithMockInDifferentThread()156 public void testStaticMockCanCoexistWithMockInDifferentThread() throws InterruptedException { 157 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 158 dummy.when(Dummy::foo).thenReturn("bar"); 159 assertEquals("bar", Dummy.foo()); 160 dummy.verify(Dummy::foo); 161 AtomicReference<String> reference = new AtomicReference<>(); 162 Thread thread = new Thread(() -> { 163 try (MockedStatic<Dummy> dummy2 = Mockito.mockStatic(Dummy.class)) { 164 dummy2.when(Dummy::foo).thenReturn("qux"); 165 reference.set(Dummy.foo()); 166 } 167 }); 168 thread.start(); 169 thread.join(); 170 assertEquals("qux", reference.get()); 171 dummy.when(Dummy::foo).thenReturn("bar"); 172 assertEquals("bar", Dummy.foo()); 173 dummy.verify(Dummy::foo, times(2)); 174 } 175 } 176 177 @Test testStaticMockMustBeExclusiveInScopeWithinThread()178 public void testStaticMockMustBeExclusiveInScopeWithinThread() { 179 assertThatThrownBy( 180 () -> { 181 try ( 182 MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class); 183 MockedStatic<Dummy> duplicate = Mockito.mockStatic(Dummy.class) 184 ) { 185 } 186 }) 187 .isInstanceOf(MockitoException.class) 188 .hasMessageContaining("static mocking is already registered in the current thread"); 189 } 190 191 @Test testStaticMockVoid()192 public void testStaticMockVoid() { 193 try (MockedStatic<Dummy> dummy = Mockito.mockStatic(Dummy.class)) { 194 Dummy.fooVoid("bar"); 195 assertNull(Dummy.var1); 196 dummy.verify(() -> Dummy.fooVoid("bar")); 197 } 198 Dummy.fooVoid("bar"); 199 assertEquals("bar", Dummy.var1); 200 } 201 202 @Test testStaticMockMustUseValidMatchers()203 public void testStaticMockMustUseValidMatchers() { 204 try (MockedStatic<Dummy> mockedClass = Mockito.mockStatic(Dummy.class)) { 205 assertThatThrownBy( 206 () -> { 207 mockedClass.when(() -> Dummy.fooVoid("foo", any())).thenReturn(null); 208 }) 209 .hasMessageContaining("Invalid use of argument matchers!"); 210 211 Dummy.fooVoid("foo", "bar"); 212 } 213 } 214 215 static class Dummy { 216 217 static String var1 = null; 218 foo()219 static String foo() { 220 return "foo"; 221 } 222 fooVoid(String var2)223 static void fooVoid(String var2) { 224 var1 = var2; 225 } 226 fooVoid(String var2, String var3)227 static void fooVoid(String var2, String var3) { 228 var1 = var2; 229 } 230 } 231 } 232