如何在单元测试中忽略 @PreAuthorize(“isAuthenticated()”) 注解?

huangapple go评论79阅读模式
英文:

How to ignore @PreAuthorize("isAuthenticated()") annotation in Unit Test?

问题

我编写了测试类:

@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); // 错误1

            Profile retrievedProfile = profileService.getUserProfile(user); // 错误2

            assertEquals("Interest sets should match", interestSet, retrievedProfile.getInterests());
        }
    }
}

但是在有注释的行 错误1错误2 处发生错误,我已经找出了问题所在,但我不知道如何修复它或是否有任何解决方法。

问题出在这里:

@Service
public class ProfileService {

    @Autowired
    ProfileDao profileDao;

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

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

这些 @PreAuthorize("isAuthenticated()") 注解引起了问题,因为当我尝试在我的单元测试中使用这两个方法时,我会得到这个异常:(AuthenticationCredentialsNotFoundException: An Authentication object was not found in the 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)

如果我删除这些注解,我的测试就会通过。所以你知道我如何修复我的测试吗?

英文:

I wrote 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(&quot;test1@testing.com&quot;, &quot;testPass&quot;),
new SiteUser(&quot;test2@testing.com&quot;, &quot;testPass&quot;),
new SiteUser(&quot;test3@testing.com&quot;, &quot;testPass&quot;),
};
private String[][] interests = {
{&quot;music&quot;, &quot;guitar_xxxxxx&quot;, &quot;plants&quot;},
{&quot;music&quot;, &quot;music&quot;, &quot;philosophy_19&quot;},
{&quot;random&quot;, &quot;football&quot;},
};
@Test
public void testInterests() {
for(int i=0; i&lt;users.length; i++) {
SiteUser user = users[i];
String[] interestArray = interests[i];
userService.register(user);
HashSet&lt;Interest&gt; interestSet = new HashSet&lt;&gt;();
for(String interestText : interestArray) {
Interest interest = interestService.createIfNotExists(interestText);
interestSet.add(interest);
assertNotNull(&quot;interest should not be null&quot;, interest);
assertNotNull(&quot;Interest should have ID&quot;, interest.getId());
assertEquals(&quot;Text should match&quot;, interestText, interest.getName());
}
Profile profile = new Profile(user);
profile.setInterests(interestSet);
profileService.save(profile); // ERROR 1
Profile retrievedProfile = profileService.getUserProfile(user); // ERROR 2
assertEquals(&quot;Interest sets should match&quot;, interestSet, retrievedProfile.getInterests());
}
}
}

But this error happens on lines that have comments ERROR 1 and ERROR 2 and I found out why is that happening however I don't know how to fix it or if there's any workaround.

Problem is in here:

@Service
public class ProfileService {
@Autowired
ProfileDao profileDao;
@PreAuthorize(&quot;isAuthenticated()&quot;) // ERROR 1
public void save(Profile profile) {
profileDao.save(profile);
}
@PreAuthorize(&quot;isAuthenticated()&quot;) // ERROR 2
public Profile getUserProfile(SiteUser user) {
return profileDao.findByUser(user);
}
}

These '@PreAuthorize("isAuthenticated()")' annotations are causing the problem, because when I try to use those two methods in my UnitTest, I'm getting this exception: (AuthenticationCredentialsNotFoundException: An Authentication object was not found in the 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(&lt;generated&gt;)
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)

And if I remove these annotations, my test passes. So do you know how can I fix my tests?

答案1

得分: 3

为什么要跳过这些注解?你尝试过使用 @WithMockUser 来在上下文中添加一个模拟用户吗?

你可以在这里找到如何使用该注解的信息。

英文:

Why do you want to skip those annotations? did you tried @WithMockUser to have a mocked user as part of your context?

Here you have how to use that annotation.

huangapple
  • 本文由 发表于 2020年10月7日 18:26:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/64242132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定