【问题标题】:Spring.NoSuchBeanDefinitionException intefering with <pre-post-annotations="enabled"/>?Spring.NoSuchBeanDefinitionException 干扰 <pre-post-annotations="enabled"/>?
【发布时间】:2013-11-17 16:06:39
【问题描述】:

注意:我解决了这个问题。查看自己的答案:)

我有一个单元测试来测试 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 注释。任何人都知道这怎么可能?这让我很困惑。

提前致谢!

【问题讨论】:

  • 你能显示你声明&lt;security:authentication-manager alias="authenticationManager"&gt;的test-context.xml部分吗?请参阅此处的答案对您有用。我不确定发生了什么,但我正在努力提供帮助 =) stackoverflow.com/questions/5403818/…
  • 您好,加布里​​埃尔,感谢您的回复。我现在真的让它工作了。请参阅我自己的答案 :) 感谢您的帮助! 是不需要的,因为这实际上是一个我没有测试的抽象层。 (我通过用户界面测试)

标签: java spring spring-security


【解决方案1】:

好吧,我花了一段时间,但我终于让它工作了。

基本上我犯了两个主要错误,其中一个作为问题的读者你是看不到的。

在我的 UserService 类中,我有以下代码:

  @Override
  @PreAuthorize("hasRole('ADMIN_ROLE')")
  public void deleteUser(String username) {
    // implementation of the method
  }

这导致某种死锁导致 Spring 给出 Spring.NoSuchBeanDefinitionException 错误。我不知道为什么,但是当 Spring 实例化这个类而标签 annotations = enabled 存在时,Spring 实际上不能实例化 userService 类。

我的第二个错误和新的学习点: 使用@PreAuthorize 注解时,请始终确保它所在的类是由spring 上下文实例化的。就我而言,我在自己的测试类中有该方法,该方法未由 spring 上下文实例化。它确实有 @RunWith(SpringJUnit4ClassRunner.class) 注释,但显然这不是为 Spring 做的:)

感谢您的帮助:)

【讨论】:

    猜你喜欢
    • 2011-03-31
    • 2014-12-20
    • 1970-01-01
    • 2012-02-11
    • 2015-02-09
    • 2012-07-17
    • 2019-06-17
    • 2015-02-12
    • 2011-04-02
    相关资源
    最近更新 更多