注意:我修正了这个问题。看到自己的答案:)
我有一个单元测试,用于测试spring security中的不同角色。
所有的身份验证和授权都是通过用户界面实现的,但我似乎无法在单元测试中使用它。这是我的单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/test-context.xml"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class UserServiceTest {
@Autowired
UserService userService;
@Test
public void UserNameAdminMustBeFound(){
UserDetails userDetails = userService.loadUserByUsername("admin");
assertEquals(userDetails.getUsername(), "admin");
}
@Test (expected = UsernameNotFoundException.class)
public void UserNotFoundMustThrowException(){
userService.loadUserByUsername("NotExistingUser");
}
@Test
public void userWithAdminRoleHasAccessToTheMethod(){
// admin has ADMIN_ROLE
UserDetails userDetails = userService.loadUserByUsername ("admin");
assertEquals("admin", userDetails.getPassword());
this.dummyMethod();
}
@Test(expected = AccessDeniedException.class)
public void userWithReadRoleHasNOAccessToTheMethod(){
// viewer has VIEWER_ROLE (and thus no ADMIN_ROLE)
UserDetails userDetails = userService.loadUserByUsername ("viewer");
assertEquals("viewer", userDetails.getPassword());
this.dummyMethod();
}
@PreAuthorize("hasRole('ADMIN_ROLE')")
private void dummyMethod(){
System.out.println("dummyMethod reached");
}
}
如果我注释掉最后一个测试'userWithReadRoleHasNOAccessToTheMethod',一切正常。这是最后一个不会抛出异常AccessDeniedException的测试。这是因为我需要在我的测试环境中使用标签global-method-security pre-post-annotations =“enabled”。
然而,这里有趣,如果我将这个标签添加到我的test-context.xml中,我会在所有单元测试中得到一个非常不同的错误:
Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@43244fd9] to prepare test instance [com.sysunite.qms.services.UserServiceTest@4f651ff]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.sysunite.qms.services.UserServiceTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.sysunite.ccy.pms.qms.security.UserService com.sysunite.qms.services.UserServiceTest.userService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sysunite.ccy.pms.qms.security.UserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.sysunite.ccy.pms.qms.security.UserService com.sysunite.qms.services.UserServiceTest.userService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sysunite.ccy.pms.qms.security.UserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sysunite.ccy.pms.qms.security.UserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
它说我没有使用id userService定义bean,但之前它已经工作了,它显然在我的test-context.xml中:
<bean id="userService" class="com.sysunite.ccy.pms.qms.security.UserService">
<property name="store" ref="quadStore"/>
<property name="instanceService" ref="instanceService"/>
</bean>
<security:global-method-security pre-post-annotations="enabled"/>
同样,如果我注释掉pre-post-annotations = enabled标签,一切正常,但我无法测试@preAuthorize注释。任何人都知道这有可能吗?这让我很困惑。
提前致谢!
答案 0 :(得分:0)
好吧,我花了一段时间,但我终于开始工作了。
基本上我犯了两个重大错误,其中一个是你作为问题的读者看不到的。
在我的UserService类中,我有以下代码:
@Override
@PreAuthorize("hasRole('ADMIN_ROLE')")
public void deleteUser(String username) {
// implementation of the method
}
这导致某种死锁导致Spring给出Spring.NoSuchBeanDefinitionExceptionerror。我不确定为什么,但是当Spring在实例化这个类时,标签annotations = enabled就在那里,Spring实际上可以不实例化userService类。
我的第二个错误和新学习点: 使用@PreAuthorize批注时,请始终确保弹出上下文实例化其所在的类。在我的例子中,我在我自己的测试类中使用了方法,该方法没有被spring上下文实例化。它确实有@RunWith(SpringJUnit4ClassRunner.class)注释,但显然不是为Spring做的:)
感谢您的帮助:)