无论存根权限如何,带有 checkPermission 的 Apache shiro 单元测试都会通过

Posted

技术标签:

【中文标题】无论存根权限如何,带有 checkPermission 的 Apache shiro 单元测试都会通过【英文标题】:Apache shiro unit test with checkPermission passes regardless of stubbed permission 【发布时间】:2018-11-10 11:46:23 【问题描述】:

使用 Shiro starter 1.4.0 运行 spring boot 1.5.12

尝试编写一些单元测试来测试使用 Subject 接口的 checkPermission 检查权限的静态类。

我正在模拟 shiro 主题并存根 isPermitted 方法以针对特定权限字符串返回 false...但由于某种原因,它在执行 Subject.checkPermission 时通过。

Subject subjectUnderTest = mock(Subject.class);
when(subjectUnderTest.isAuthenticated()).thenReturn(true);
when(subjectUnderTest.isPermitted(eq("review:edit:regional"))).thenReturn(false);
setSubject(subjectUnderTest);
subjectUnderTest.checkPermission("review:edit:regional");

我对 Mockito 还很陌生,但在这种情况下,鉴于 isPermitted 存根返回 false,我期望 checkPermission 会抛出 AuthorizationException。

如果我将实现更改为使用 isPermitted,那么测试将按预期运行..但当前实现正在使用 checkPermission...

【问题讨论】:

【参考方案1】:

Subject 接口的方法checkPermission() 不会在自身上调用isPermitted(),而是在抽象AuthorizingRealm 上调用。 checkPermission() 的调用链如下:

Subject.checkPermissions()->
    DelegatingSubject.checkPermissions()->
        Authoriser.checkPermission()->
            AuthorizingRealm.checkPermission()->
            AuthorizingRealm.isPermitted()

因此,在Subject 上模拟isPermitted() 将无效,因为checkPermission() 永远不会在此对象上调用它。要实现预期的行为,您必须在 AuthorizingRealmAuthorizingSecurityManager 上模拟该方法,以防对您的 SecurityManager 的调用在测试中可用。

【讨论】:

谢谢。我在玩 Mocked subject.checkPermission 然后进入了 mockito 的 void stubbing 方法。所以似乎这里的正确方法是使用 doNothing 和 doThrow 来模拟 checkPermission 通过和失败测试。doThrow() 将抛出一个 shiro AuthorizationException。

以上是关于无论存根权限如何,带有 checkPermission 的 Apache shiro 单元测试都会通过的主要内容,如果未能解决你的问题,请参考以下文章

带有列表的 Python 字典,如何在节俭的存根代码中描述它?

带有存根的子类的 Python 2.7 类型提示

无论如何在Android中将Drawable转换为int

RhinoMocks - 存根返回参数的方法

什么是“存根”?

OCMock:存根从不匹配签名