View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
5    */
6   package mockit;
7   
8   import static org.junit.jupiter.api.Assertions.assertEquals;
9   import static org.junit.jupiter.api.Assertions.assertFalse;
10  import static org.junit.jupiter.api.Assertions.assertNotNull;
11  import static org.junit.jupiter.api.Assertions.assertNull;
12  import static org.junit.jupiter.api.Assertions.assertThrows;
13  import static org.junit.jupiter.api.Assertions.assertTrue;
14  
15  import java.util.Collections;
16  import java.util.Map;
17  
18  import javax.security.auth.Subject;
19  import javax.security.auth.callback.CallbackHandler;
20  import javax.security.auth.login.AppConfigurationEntry;
21  import javax.security.auth.login.Configuration;
22  import javax.security.auth.login.LoginContext;
23  import javax.security.auth.login.LoginException;
24  import javax.security.auth.spi.LoginModule;
25  
26  import org.junit.jupiter.api.Test;
27  
28  public final class MockLoginContextTest {
29  
30      @Test
31      public void mockJREMethodAndConstructorUsingAnnotatedMockClass() throws Exception {
32          new MockLoginContext();
33  
34          new LoginContext("test", (CallbackHandler) null).login();
35      }
36  
37      public static class MockLoginContext extends MockUp<LoginContext> {
38          @Mock
39          public void $init(String name, CallbackHandler callbackHandler) {
40              assertEquals("test", name);
41              assertNull(callbackHandler);
42          }
43  
44          @Mock
45          public void login() {
46          }
47  
48          @Mock
49          public Subject getSubject() {
50              return null;
51          }
52      }
53  
54      @Test
55      public void mockJREMethodAndConstructorWithMockUpClass() throws Exception {
56          new MockUp<LoginContext>() {
57              @Mock
58              void $init(String name) {
59                  assertEquals("test", name);
60              }
61  
62              @Mock
63              void login() throws LoginException {
64                  throw new LoginException();
65              }
66          };
67  
68          assertThrows(LoginException.class, () -> {
69              new LoginContext("test").login();
70          });
71      }
72  
73      @Test
74      public void mockJREClassWithStubs() throws Exception {
75          new MockLoginContextWithStubs();
76  
77          LoginContext context = new LoginContext("");
78          context.login();
79          context.logout();
80      }
81  
82      final class MockLoginContextWithStubs extends MockUp<LoginContext> {
83          @Mock
84          void $init(String s) {
85          }
86  
87          @Mock
88          void logout() {
89          }
90  
91          @Mock
92          void login() {
93          }
94      }
95  
96      @Test
97      public void proceedIntoRealImplementationsOfMockedMethods() throws Exception {
98          // Create objects to be exercised by the code under test:
99          Configuration configuration = new Configuration() {
100             @Override
101             public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
102                 Map<String, ?> options = Collections.emptyMap();
103                 return new AppConfigurationEntry[] { new AppConfigurationEntry(TestLoginModule.class.getName(),
104                         AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, options) };
105             }
106         };
107         LoginContext loginContext = new LoginContext("test", null, null, configuration);
108 
109         // Set up mocks:
110         ProceedingMockLoginContext mockInstance = new ProceedingMockLoginContext();
111 
112         // Exercise the code under test:
113         assertNull(loginContext.getSubject());
114         loginContext.login();
115         assertNotNull(loginContext.getSubject());
116         assertTrue(mockInstance.loggedIn);
117 
118         mockInstance.ignoreLogout = true;
119         loginContext.logout();
120         assertTrue(mockInstance.loggedIn);
121 
122         mockInstance.ignoreLogout = false;
123         loginContext.logout();
124         assertFalse(mockInstance.loggedIn);
125     }
126 
127     static final class ProceedingMockLoginContext extends MockUp<LoginContext> {
128         boolean ignoreLogout;
129         boolean loggedIn;
130 
131         @Mock
132         void login(Invocation inv) throws LoginException {
133             LoginContext it = inv.getInvokedInstance();
134 
135             try {
136                 inv.proceed();
137                 loggedIn = true;
138             } finally {
139                 it.getSubject();
140             }
141         }
142 
143         @Mock
144         void logout(Invocation inv) throws LoginException {
145             if (!ignoreLogout) {
146                 inv.proceed();
147                 loggedIn = false;
148             }
149         }
150     }
151 
152     public static class TestLoginModule implements LoginModule {
153         @Override
154         public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
155                 Map<String, ?> options) {
156         }
157 
158         @Override
159         public boolean login() {
160             return true;
161         }
162 
163         @Override
164         public boolean commit() {
165             return true;
166         }
167 
168         @Override
169         public boolean abort() {
170             return false;
171         }
172 
173         @Override
174         public boolean logout() {
175             return true;
176         }
177     }
178 }