/*
* 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 javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import org.junit.*;
import org.junit.rules.*;
import static org.junit.Assert.*;
import static mockit.Deencapsulation.*;
public final class MockLoginContextTest
{
@Rule public final ExpectedException thrown = ExpectedException.none();
@Test
public void mockJREMethodAndConstructorUsingAnnotatedMockClass() throws Exception
{
new MockLoginContext();
new LoginContext("test", (CallbackHandler) null).login();
}
public static class MockLoginContext extends MockUp<LoginContext>
{
@Mock
public void $init(String name, CallbackHandler callbackHandler)
{
assertEquals("test", name);
assertNull(callbackHandler);
}
@Mock
public void login() {}
@Mock
public Subject getSubject() { return null; }
}
@Test
public void mockJREMethodAndConstructorWithMockUpClass() throws Exception
{
thrown.expect(LoginException.class);
new MockUp<LoginContext>() {
@Mock
void $init(String name) { assertEquals("test", name); }
@Mock
void login() throws LoginException
{
throw new LoginException();
}
};
new LoginContext("test").login();
}
@Test
public void mockJREClassWithStubs() throws Exception
{
new MockLoginContextWithStubs();
LoginContext context = new LoginContext("");
context.login();
context.logout();
}
final class MockLoginContextWithStubs extends MockUp<LoginContext>
{
@Mock void $init(String s) {}
@Mock void logout() {}
@Mock void login() {}
}
@Test
public void accessMockedInstance() throws Exception
{
final Subject testSubject = new Subject();
new MockUp<LoginContext>() {
@Mock
void $init(Invocation inv, String name, Subject subject)
{
LoginContext it = inv.getInvokedInstance();
assertNotNull(name);
assertSame(testSubject, subject);
assertNotNull(it);
setField(it, subject); // forces setting of private field, since no setter is available
}
@Mock
void login(Invocation inv)
{
LoginContext it = inv.getInvokedInstance();
assertNotNull(it);
assertNull(it.getSubject()); // returns null until the subject is authenticated
setField(it, "loginSucceeded", true); // private field set to true when login succeeds
}
@Mock
void logout(Invocation inv)
{
LoginContext it = inv.getInvokedInstance();
assertNotNull(it);
assertSame(testSubject, it.getSubject());
}
};
LoginContext theMockedInstance = new LoginContext("test", testSubject);
theMockedInstance.login();
theMockedInstance.logout();
}
@Test
public void proceedIntoRealImplementationsOfMockedMethods() throws Exception
{
// Create objects to be exercised by the code under test:
Configuration configuration = new Configuration() {
@Override
public AppConfigurationEntry[] getAppConfigurationEntry(String name)
{
Map<String, ?> options = Collections.emptyMap();
return new AppConfigurationEntry[]
{
new AppConfigurationEntry(
TestLoginModule.class.getName(),
AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT, options)
};
}
};
LoginContext loginContext = new LoginContext("test", null, null, configuration);
// Set up mocks:
ProceedingMockLoginContext mockInstance = new ProceedingMockLoginContext();
// Exercise the code under test:
assertNull(loginContext.getSubject());
loginContext.login();
assertNotNull(loginContext.getSubject());
assertTrue(mockInstance.loggedIn);
mockInstance.ignoreLogout = true;
loginContext.logout();
assertTrue(mockInstance.loggedIn);
mockInstance.ignoreLogout = false;
loginContext.logout();
assertFalse(mockInstance.loggedIn);
}
static final class ProceedingMockLoginContext extends MockUp<LoginContext>
{
boolean ignoreLogout;
boolean loggedIn;
@Mock
void login(Invocation inv) throws LoginException
{
LoginContext it = inv.getInvokedInstance();
try {
inv.proceed();
loggedIn = true;
}
finally {
it.getSubject();
}
}
@Mock
void logout(Invocation inv) throws LoginException
{
if (!ignoreLogout) {
inv.proceed();
loggedIn = false;
}
}
}
public static class TestLoginModule implements LoginModule
{
@Override
public void initialize(
Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
Map<String, ?> options)
{
}
@Override public boolean login() { return true; }
@Override public boolean commit() { return true; }
@Override public boolean abort() { return false; }
@Override public boolean logout() { return true; }
}
}