Apache Shiro's Test学习笔记

来源:互联网 发布:清华北大 知乎 编辑:程序博客网 时间:2024/05/17 07:13

Shiro的subject实质上是当前执行用户的一个特定的视图,subject能够被访问的前提条件:

    1.subject的实例必须被创建;

    2.subject实例必须和当前执行的线程绑定;

    3.subject实例在线程结束后必须解除绑定,以保证线程可以被线程池清理。


AbstractShiroTest

import org.apache.shiro.SecurityUtils;import org.apache.shiro.UnavailableSecurityManagerException;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.subject.Subject;import org.apache.shiro.subject.support.SubjectThreadState;import org.apache.shiro.util.LifecycleUtils;import org.apache.shiro.util.ThreadState;import org.junit.AfterClass;/** * Abstract test case enabling Shiro in test environments. */public abstract class AbstractShiroTest {    private static ThreadState subjectThreadState;    public AbstractShiroTest() {    }    /**     * Allows subclasses to set the currently executing {@link Subject} instance.     *     * @param subject the Subject instance     */    protected void setSubject(Subject subject) {        clearSubject();        subjectThreadState = createThreadState(subject);        subjectThreadState.bind();    }    protected Subject getSubject() {        return SecurityUtils.getSubject();    }    protected ThreadState createThreadState(Subject subject) {        return new SubjectThreadState(subject);    }    /**     * Clears Shiro's thread state, ensuring the thread remains clean for future test execution.     */    protected void clearSubject() {        doClearSubject();    }    private static void doClearSubject() {        if (subjectThreadState != null) {            subjectThreadState.clear();            subjectThreadState = null;        }    }    protected static void setSecurityManager(SecurityManager securityManager) {        SecurityUtils.setSecurityManager(securityManager);    }    protected static SecurityManager getSecurityManager() {        return SecurityUtils.getSecurityManager();    }    @AfterClass    public static void tearDownShiro() {        doClearSubject();        try {            SecurityManager securityManager = getSecurityManager();            LifecycleUtils.destroy(securityManager);        } catch (UnavailableSecurityManagerException e) {            //we don't care about this when cleaning up the test environment            //(for example, maybe the subclass is a unit test and it didn't            // need a SecurityManager instance because it was using only             // mock Subject instances)        }        setSecurityManager(null);    }}

    ExampleShiroUnitTest

import org.apache.shiro.subject.Subject;import org.junit.After;import org.junit.Test;import static org.easymock.EasyMock.*;/** * Simple example test class showing how one may perform unit tests for code that requires Shiro APIs. */public class ExampleShiroUnitTest extends AbstractShiroTest {    @Test    public void testSimple() {        //1.  Create a mock authenticated Subject instance for the test to run:        Subject subjectUnderTest = createNiceMock(Subject.class);        expect(subjectUnderTest.isAuthenticated()).andReturn(true);        //2. Bind the subject to the current thread:        setSubject(subjectUnderTest);        //perform test logic here.  Any call to         //SecurityUtils.getSubject() directly (or nested in the         //call stack) will work properly.    }    @After    public void tearDownSubject() {        //3. Unbind the subject from the current thread:        clearSubject();    }}


Unit下集成测试(ExampleShiroIntegrationTest)

import org.apache.shiro.config.IniSecurityManagerFactory;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.Factory;import org.junit.After;import org.junit.BeforeClass;import org.junit.Test;public class ExampleShiroIntegrationTest extends AbstractShiroTest {    @BeforeClass    public static void beforeClass() {        //0.  Build and set the SecurityManager used to build Subject instances used in your tests        //    This typically only needs to be done once per class if your shiro.ini doesn't change,        //    otherwise, you'll need to do this logic in each test that is different        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:test.shiro.ini");        setSecurityManager(factory.getInstance());    }    @Test    public void testSimple() {        //1.  Build the Subject instance for the test to run:        Subject subjectUnderTest = new Subject.Builder(getSecurityManager()).buildSubject();        //2. Bind the subject to the current thread:        setSubject(subjectUnderTest);        //perform test logic here.  Any call to         //SecurityUtils.getSubject() directly (or nested in the         //call stack) will work properly.    }    @AfterClass    public void tearDownSubject() {        //3. Unbind the subject from the current thread:        clearSubject();    }}



0 0
原创粉丝点击