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

时间:2018-05-31 12:46:50

标签: unit-testing shiro

使用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 个答案:

答案 0 :(得分:1)

Subject界面的方法checkPermission()不会在自身上调用isPermitted(),而在抽象AuthorizingRealm上调用checkPermission()Subject.checkPermissions()-> DelegatingSubject.checkPermissions()-> Authoriser.checkPermission()-> AuthorizingRealm.checkPermission()-> AuthorizingRealm.isPermitted() 的调用链如下所示:

isPermitted()

因此,Subject上的checkPermission()模仿将无效,因为AuthorizingRealm永远不会在此对象上调用它。要实现预期的行为,您必须在AuthorizingSecurityManager上模拟该方法,或者在SecurityManager上模拟您 /// <summary> /// Method that gets called by ManagedResource.WriteData() in project CodeAnalysis during code /// emitting to get the data for an embedded resource file. /// </summary> /// <param name="resourceFullFilename">full path and filename for resource file to embed</param> /// <returns>MemoryStream containing .resource file data - caller will dispose it</returns> private static MemoryStream ProvideResourceData(string resourceFullFilename) { MemoryStream shortLivedBackingStream = new MemoryStream(); using (ResourceWriter resourceWriter = new ResourceWriter(shortLivedBackingStream)) { using (ResXResourceReader resourceReader = new ResXResourceReader(resourceFullFilename)) { IDictionaryEnumerator dictionaryEnumerator = resourceReader.GetEnumerator(); while (dictionaryEnumerator.MoveNext()) { string resourceKey = dictionaryEnumerator.Key as string; if (resourceKey != null) // Should not be possible resourceWriter.AddResource(resourceKey, dictionaryEnumerator.Value); } } } return new MemoryStream(shortLivedBackingStream.GetBuffer()); } 的{​​{1}}调用。