Shiro 单元测试
单元测试主要是关于测试您的代码,而仅是在有限范围内的代码。考虑到 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
超类将在所有测试后将其从线程中解除绑定。