<a name="Testing-TestingwithApacheShiro"></a>
Testing with Apache Shiro
=========================

This part of the documentation explains how to enable Shiro in unit tests.

<a name="Testing-Whattoknowfortests"></a>
What to know for tests
----------------------

As we've already covered in the [Subject reference](subject.html "Subject"), we know that a Subject is security-specific view of the 'currently executing' user, and that Subject instances are always bound to a thread to ensure we know _who_ is executing logic at any time during the thread's execution.

This means three basic things must always occur in order to support being able to access the currently executing Subject:

1.  A `Subject` instance must be created
2.  The `Subject` instance must be _bound_ to the currently executing thread.
3.  After the thread is finished executing (or if the thread's execution results in a `Throwable`), the `Subject` must be _unbound_ to ensure that the thread remains 'clean' in any thread-pooled environment.

Shiro has architectural components that perform this bind/unbind logic automatically for a running application. For example, in a web application, the root Shiro Filter performs this logic when [filtering a request](http://shiro.apache.org/static/current/apidocs/org/apache/shiro/web/servlet/AbstractShiroFilter.html#doFilterInternal-javax.servlet.ServletRequest-javax.servlet.ServletResponse-javax.servlet.FilterChain-). But as test environments and frameworks differ, we need to perform this bind/unbind logic ourselves for our chosen test framework.

<a name="Testing-TestSetup"></a>
Test Setup
----------

So we know after creating a `Subject` instance, it must be _bound_ to thread. After the thread (or in this case, a test) is finished executing, we must _unbind_ the Subject to keep the thread 'clean'.

Luckily enough, modern test frameworks like JUnit and TestNG natively support this notion of 'setup' and 'teardown' already. We can leverage this support to simulate what Shiro would do in a 'complete' application. We've created a base abstract class that you can use in your own testing below - feel free to copy and/or modify as you see fit. It can be used in both unit testing and integration testing (we're using JUnit in this example, but TestNG works just as well):

<a name="Testing-AbstractShiroTest"></a>
#[[###AbstractShiroTest]]#

``` java
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);
    }
}
```

#warning('Testing &amp; Frameworks', 'The code in the <code>AbstractShiroTest</code> class uses Shiro''s <code>ThreadState</code> concept and a static SecurityManager.  These techniques are useful in tests and in framework code, but rarely ever used in application code.
<p>Most end-users working with Shiro who need to ensure thread-state consistency will almost always use Shiro''s automatic management mechanisms, namely the `Subject.associateWith` and the `Subject.execute` methods. These methods are covered in the reference on <a href="subject.html#Subject-ThreadAssociation">Subject thread association</a>).</p>')

<a name="Testing-UnitTesting"></a>
Unit Testing
------------

Unit testing is mostly about testing your code and only your code in a limited scope. When you take Shiro into account, what you really want to focus on is that your code works correctly with Shiro's _API_ - you don't want to necessarily test that Shiro's implementation is working correctly (that's something that the Shiro development team must ensure in Shiro's code base).

Testing to see if Shiro's implementations work in conjunction with your implementations is really integration testing (discussed below).

<a name="Testing-ExampleShiroUnitTest"></a>
#[[###ExampleShiroUnitTest]]#

Because unit tests are better suited for testing your own logic (and not any implementations your logic might call), it is a great idea to _mock_ any APIs that your logic depends on. This works very well with Shiro - you can mock the `Subject` interface and have it reflect whatever conditions you want your code under test to react to. We can leverage modern mock frameworks like [EasyMock](http://easymock.org/) and [Mockito](http://site.mockito.org) to do this for us.

But as stated above, the key in Shiro tests is to remember that any Subject instance (mock or real) must be bound to the thread during test execution. So all we need to do is bind the mock Subject to ensure things work as expected.

(this example uses EasyMock, but Mockito works equally as well):

``` java
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();
    }

}
```

As you can see, we're not setting up a Shiro `SecurityManager` instance or configuring a `Realm` or anything like that. We're simply creating a mock `Subject` instance and binding it to the thread via the `setSubject` method call. This will ensure that any calls in our test code or in the code we're testing to `SecurityUtils.getSubject()` will work correctly.

Note that the `setSubject` method implementation will bind your mock Subject to the thread and it will remain there until you call `setSubject` with a different `Subject` instance or until you explicitly clear it from the thread via the `clearSubject()` call.

How long you keep the subject bound to the thread (or swap it out for a new instance in a different test) is up to you and your testing requirements.

<a name="Testing-tearDownSubject%28%29"></a>
#[[####tearDownSubject()]]#

The `tearDownSubject()` method in the example uses a Junit 4 annotation to ensure that the Subject is cleared from the thread after every test method is executed, no matter what. This requires you to set up a new `Subject` instance and set it (via `setSubject`) for every test that executes.

This is not strictly necessary however. For example, you could just bind a new Subject instance (via `setSujbect`) at the beginning of every test, say, in an `@Before`-annotated method. But if you're going to do that, you might as well have the `@After tearDownSubject()` method to keep things symmetrical and 'clean'.

You can mix and match this setup/teardown logic in each method manually or use the @Before and @After annotations as you see fit. The `AbstractShiroTest` super class will however unbind the Subject from the thread after all tests because of the `@AfterClass` annotation in its `tearDownShiro()` method.

<a name="Testing-IntegrationTesting"></a>
Integration Testing
-------------------

Now that we've covered unit test setup, let's talk a bit about integration testing. Integration testing is testing implementations across API boundaries. For example, testing that implementation A works when calling implementation B and that implementation B does what it is supposed to.

You can easily perform integration testing in Shiro as well. Shiro's `SecurityManager` instance and things it wraps (like Realms and SessionManager, etc) are all very lightweight POJOs that use very little memory. This means you can create and tear down a `SecurityManager` instance for every test class you execute. When your integration tests run, they will be using 'real' `SecurityManager` and `Subject` instances like your application will be using at runtime.

<a name="Testing-ExampleShiroIntegrationTest"></a>
#[[###ExampleShiroIntegrationTest]]#

The example code below looks almost identical to the Unit Test example above, but the 3 step process is slightly different:

1.  There is now a step '0', which sets up a 'real' SecurityManager instance.
2.  Step 1 now constructs a 'real' Subject instance with the `Subject.Builder` and binds it to the thread.

Thread binding and unbinding (steps 2 and 3) function the same as the Unit Test example.

``` java
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();
    }
}
```

As you can see, a concrete `SecurityManager` implementation is instantiated and made accessible for the remainder of the test via the `setSecurityManager` method. Test methods can then use this `SecurityManager` when using the `Subject.Builder` later via the `getSecurityManager()` method.

Also note that the `SecurityManager` instance is set up once in a `@BeforeClass` setup method - a fairly common practice for most test classes. But if you wanted to, you could create a new `SecurityManager` instance and set it via `setSecurityManager` at any time from any test method - for example, you might reference two different .ini files to build a new `SecurityManager` depending on your test requirements.

Finally, just as with the Unit Test example, the `AbstractShiroTest` super class will clean up all Shiro artifacts (any remaining `SecurityManager` and `Subject` instance) via its `@AfterClass tearDownShiro()` method to ensure the thread is 'clean' for the next test class to run.

#lendAHandDoc()

<input type="hidden" id="ghEditPage" value="testing.md.vtl"></input>
