11

我在 Spring MVC Controller 中定义了这个方法:

@RequestMapping(value = "{id}/content", method=RequestMethod.POST)
@PreAuthorize("principal.user.userAccount instanceof T(com.anonym.model.identity.PedagoAccount) AND principal.user.userAccount.userId == #object.pedago.userId AND #form.id == #object.id")
public String modifyContent(@PathVariable("id") Project object, @Valid  @ModelAttribute("form") ProjectContentForm form) {
    ....
}

然后在我的 JUnit 测试中,我想调用这个方法并确保 PreAuthorize 条件得到验证。但是,当我在我的 JUnit 测试中使用错误帐户设置用户主体时,没有错误并且该方法完成。似乎注释被绕过了。
但是当我以正常方式(不是测试)调用此方法时,PreAuthorize 得到验证。

如果可能的话,如何在 junit 测试中测试这个注释,如果它抛出一个异常,如何捕获异常?

谢谢,
尼古拉斯

4

1 回答 1

15

由于您想测试通过 Spring AOP 实现的功能,因此您需要使用Spring TestContext框架来针对应用程序上下文运行测试。

然后,您使用最少的安全配置创建一个基本测试:

abstract-security-test.xml

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider user-service-ref = "userService" />
</security:authentication-manager>

<security:global-method-security pre-post-annotations="enabled" />

<bean id = "userService" class = "..." />

AbstractSecurityTest.java

@ContextConfiguration("abstract-security-test.xml")
abstract public class AbstractSecurityTest {
    @Autowired
    private AuthenticationManager am;

    @After
    public void clear() {
        SecurityContextHolder.clearContext();
    }

    protected void login(String name, String password) {
        Authentication auth = new UsernamePasswordAuthenticationToken(name, password);
        SecurityContextHolder.getContext().setAuthentication(am.authenticate(auth));
    }
}

现在您可以在测试中使用它:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(...)
public class CreatePostControllerSecurityTest extends AbstractSecurityTest {
    ...

    @Test
    @ExpectedException(AuthenticationCredentialsNotFoundException.class)
    public void testNoAuth() {
        controller.modifyContent(...);
    }

    @Test
    @ExpectedException(AccessDeniedException.class)
    public void testAccessDenied() {
        login("userWithoutAccessRight", "...");
        controller.modifyContent(...);
    }

    @Test
    public void testAuthOK() {
        login("userWithAccessRight", "...");
        controller.modifyContent(...);
    }
}
于 2011-03-23T10:45:57.757 回答