阅读(3351) (0)

Shiro 单元测试

2021-06-19 15:42:38 更新

单元测试主要是关于测试您的代码,而仅是在有限范围内的代码。考虑到 Shiro 时,您 true 要关注的是您的代码可以与 Shiro 的* API *一起正常工作-您并不需要测试 Shiro 的实现是否正常工作(这是 Shiro 开发团队必须确保的事情)在 Shiro 的代码库中)。

检验 Shiro 的实现是否可以与您的实现一起工作的测试实际上是集成测试(下面讨论)。

Shiro单元测试实例

因为单元测试更适合测试您自己的逻辑(而不是您的逻辑可能调用的任何实现),所以“模拟”您逻辑所依赖的任何 API 是一个好主意。这在 Shiro 上非常有效-您可以模拟​Subject​接口,并使其反映您希望被测代码对之做出反应的任何条件。我们可以利用诸如EasyMock和Mockito之类的现代模拟框架为我们完成此任务。

但是如上所述,Shiro 测试中的关键是要记住在测试执行期间必须将任何 Subject 实例(模拟或真实)绑定到线程。因此,我们要做的就是绑定模拟主题,以确保事情按预期进行。

(此示例使用 EasyMock,但 Mockito 的效果也一样):

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

}

如您所见,我们没有设置 Shiro ​SecurityManager​实例或配置​Realm​或类似的东西。我们只是在创建一个模拟​Subject​实例,并通过​setSubject​方法调用将其绑定到线程。这样可以确保测试代码或我们正在测试的​SecurityUtils.getSubject()​代码中的所有调用均能正常工作。

请注意,​setSubject​方法实现会将您的模拟 Subject 绑定到线程,并且将保留在那里,直到您使用其他​Subject​实例调用​setSubject​或通过​clearSubject()​调用从线程中明确清除它为止。

保持主题与线程绑定多长时间(或将其替换为其他测试中的新实例)取决于您和您的测试要求。

tearDownSubject()

该示例中的​tearDownSubject()​方法使用 Junit 4 注解,以确保无论执行哪种测试方法,在执行线程后都会从线程中清除 Subject。这要求您设置一个新的​Subject​实例,并为每个执行的测试(通过​setSubject​)进行设置。

但是,这并非绝对必要。例如,您可以在每个测试的开始(例如,以​@Before​Comments 的方法)(通过setSujbect)绑定一个新的 ​Subject​ 实例。但是,如果要执行此操作,则最好使用​@After tearDownSubject()​方法保持事物对称和“干净”。

您可以在每种方法中手动混合和匹配此设置/拆卸逻辑,或者使用@Before 和@AfterComments(如果您认为合适)。但是,由于所有测试中的tearDownShiro()方法中都有​@AfterClass​注解,因此​AbstractShiroTest​超类将在所有测试后将其从线程中解除绑定。