如何在单元测试中忽略@PreAuthorize("isAuthenticated()") 注解?
How to ignore @PreAuthorize("isAuthenticated()") annotation in Unit Test?
我写了测试class:
@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("test1@testing.com", "testPass"),
new SiteUser("test2@testing.com", "testPass"),
new SiteUser("test3@testing.com", "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 1 和 ERROR 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 : 在 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$c09751.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 你知道如何使用那个注释。
我写了测试class:
@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("test1@testing.com", "testPass"),
new SiteUser("test2@testing.com", "testPass"),
new SiteUser("test3@testing.com", "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 1 和 ERROR 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 : 在 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$c09751.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 你知道如何使用那个注释。