[#Testing-TestingwithApacheShiro]
= Testing with Apache Shiro
:jbake-date: 2010-03-18 00:00:00
:jbake-type: page
:jbake-status: published
:jbake-tags: documentation, testing
:idprefix:
:icons: font


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

[#Testing-Whattoknowfortests]
== What to know for tests

As we've already covered in the link:/subject.html[Subject reference], 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:

. A `Subject` instance must be created
. The `Subject` instance must be _bound_ to the currently executing thread.
. 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 link:++http://shiro.apache.org/static/current/apidocs/org/apache/shiro/web/servlet/AbstractShiroFilter.html#doFilterInternal(javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax.servlet.FilterChain)++[filtering a request]. But as test environments and frameworks differ, we need to perform this bind/unbind logic ourselves for our chosen test framework.

[#Testing-TestSetup]
== 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):

=== AbstractShiroTest

[source,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 & Frameworks
====
The code in the `AbstractShiroTest` class uses Shiro''s `ThreadState` concept and a static SecurityManager.
These techniques are useful in tests and in framework code, but rarely ever used in application code.

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 link:/subject.html#Subject-ThreadAssociation[Subject thread association].
====

<p></p>')

[#Testing-UnitTesting]
== 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).

[#Testing-ExampleShiroUnitTest]
=== 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 http://easymock.org/[EasyMock] and http://site.mockito.org[Mockito] 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):

[source,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.

[#Testing-tearDownSubject]
=== 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.

[#Testing-IntegrationTesting]
== 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.

[#Testing-ExampleShiroIntegrationTest]
=== ExampleShiroIntegrationTest

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

. There is now a step '0', which sets up a 'real' SecurityManager instance.
. 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.

[source,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.
