java - 如何在单元测试中忽略 @PreAuthorize ("isAuthenticated()") 注释?

标签 java spring-boot authentication junit

我编写了测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
@Transactional
public class ProfileTest {

@Autowired
private UserService userService;

@Autowired
private ProfileService profileService;

@Autowired
private InterestService interestService;

private SiteUser[] users = {
        new SiteUser("<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a9ddccdadd98e9ddccdaddc0c7ce87cac6c4" rel="noreferrer noopener nofollow">[email protected]</a>", "testPass"),
        new SiteUser("<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="83f7e6f0f7b1c3f7e6f0f7eaede4ade0ecee" rel="noreferrer noopener nofollow">[email protected]</a>", "testPass"),
        new SiteUser("<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="34405147400774405147405d5a531a575b59" rel="noreferrer noopener nofollow">[email protected]</a>", "testPass"),
};

private String[][] interests = {
        {"music", "guitar_xxxxxx", "plants"},
        {"music", "music", "philosophy_19"},
        {"random", "football"},
};

@Test
public void testInterests() {
    
    for(int i=0; i<users.length; i++) {
        SiteUser user = users[i];
        String[] interestArray = interests[i];
        
        userService.register(user);
        
        HashSet<Interest> interestSet = new HashSet<>();
        
        for(String interestText : interestArray) {
            Interest interest = interestService.createIfNotExists(interestText);
            interestSet.add(interest);
            
            assertNotNull("interest should not be null", interest);
            assertNotNull("Interest should have ID", interest.getId());
            assertEquals("Text should match", interestText, interest.getName());
        }
        
        Profile profile = new Profile(user);
        profile.setInterests(interestSet);
        profileService.save(profile); // ERROR 1
        
        Profile retrievedProfile = profileService.getUserProfile(user); // ERROR 2
        
        assertEquals("Interest sets should match", interestSet, retrievedProfile.getInterests());
    }
}

}

但是这个错误发生在有注释ERROR 1ERROR 2的行上,我发现了为什么会发生这种情况,但我不知道如何修复它或如果有任何解决方法。

问题出在这里:

@Service
public class ProfileService {

@Autowired
ProfileDao profileDao;

@PreAuthorize("isAuthenticated()") // ERROR 1
public void save(Profile profile) {
    profileDao.save(profile);
}

@PreAuthorize("isAuthenticated()") // ERROR 2
public Profile getUserProfile(SiteUser user) {
    return profileDao.findByUser(user);
}
}

这些 '@PreAuthorize("isAuthenticated()")' 注释导致了问题,因为当我尝试在 UnitTest 中使用这两种方法时,我收到此异常:(AuthenticationCredentialsNotFoundException: An Authentication object在 SecurityContext 中未找到):

org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:379)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:223)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at com.socialnetwork.service.ProfileService$$EnhancerBySpringCGLIB$$22c09751.save(<generated>)
at com.socialnetwork.tests.ProfileTest.testInterests(ProfileTest.java:72)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

如果我删除这些注释,我的测试就会通过。那么你知道我该如何修复我的测试吗?

最佳答案

为什么要跳过这些注释?您是否尝试过 @WithMockUser 将模拟用户作为您上下文的一部分?

Here您知道如何使用该注释。

关于java - 如何在单元测试中忽略 @PreAuthorize ("isAuthenticated()") 注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64242132/

相关文章:

java - JUnit 4 与 TestNG 6

使用 setModel() 更新 JComboBox 时出现 java.lang.IllegalStateException?

java - Swing 布局想法

java - 启用具有 JWT 安全性的 Spring Boot 2.0 Actuator 端点

java - Spring Boot Rest 响应返回 login.jsp

java - 从Java中的数组/集合的每个元素中剥离字符

php - Laravel REST API - 无限循环

email - Web应用程序中 token 认证的最佳做法?

html - 如何保持用户登录?

java - 如何将 pom.xml 添加到现有的 Netbeans web 应用程序项目?