阅读(2383) (0)

Shiro 集成测试

2021-06-21 10:42:23 更新

既然我们已经介绍了单元测试设置,那么让我们来谈谈集成测试。集成测试是跨 API 边界测试实现。例如,在调用实现 B 时测试实现 A 是否有效,而实现 B 则按预期进行测试。

您也可以在 Shiro 中轻松执行集成测试。 Shiro 的​SecurityManager​实例及其包装的东西(例如 Realms 和 SessionManager 等)都是非常轻量级的 POJO,它们使用的内存很少。这意味着您可以为执行的每个测试类创建和拆除​SecurityManager​实例。当您的集成测试运行时,它们将使用“真实” ​SecurityManager​和​Subject​实例,就像您的应用程序将在运行时使用一样。

集成测试实例

下面的示例代码看起来与上面的单元测试示例几乎相同,但是三步过程略有不同:

  • 现在有一个步骤“ 0”,它设置了一个“真实的” SecurityManager 实例。
  • 现在,第 1 步使用​Subject.Builder​构造一个“真实”主题实例,并将其绑定到线程。

线程绑定和取消绑定(步骤 2 和 3)的功能与单元测试示例相同。

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

如您所见,实例​SecurityManager​的具体实现已实例化,并可以通过​setSecurityManager​方法在其余的测试中访问。然后,稍后通过​getSecurityManager()​方法使用​Subject.Builder​时,测试方法可以使用此​SecurityManager​。

还要注意,​SecurityManager​实例是通过​@BeforeClass​设置方法设置的,这对于大多数测试类来说是相当普遍的做法。但是,如果愿意,您可以创建一个新的​SecurityManager​实例,并通过任何测试方法随时通过​setSecurityManager​对其进行设置-例如,您可以根据测试要求引用两个不同的.ini 文件来构建新的​SecurityManager​。

最后,就像单元测试示例一样,​AbstractShiroTest​超级类将通过其​@AfterClass tearDownShiro()​方法清除所有 Shiro 构件(所有剩余的​SecurityManager​和​Subject​实例),以确保线程“干净”以供下一个测试类运行。