在Spring Boot 1.4.1中,我想对使用@PreAuthorize进行限制访问的服务方法进行单元测试(而不是集成测试)。
问题是从Eclipse启动测试独奏时似乎未检查@PreAuthorize(尚未尝试使用mvn test)。
然后,如果我奇迹般地设法正确运行测试,我将尝试使用StudyService接口,而不是impl。
这是我的考试课:
@RunWith(MockitoJUnitRunner.class)
public class TestMethodSecurity {
private static final Long STUDY_ID = 1L;
@Mock
private StudyRepository studyRepository;
@InjectMocks
private StudyServiceImpl studyService;
@Before
public void setup() {
given(studyRepository.findOne(STUDY_ID)).willReturn(ModelsUtil.createStudy());
}
@Test
public void findByIdWithoutAccessRightTest() {
Study study = studyService.findById(STUDY_ID);
}
}
这是服务:
@Service
public class StudyServiceImpl implements StudyService {
@Autowired
private StudyRepository studyRepository;
@Override
@PreAuthorize("hasAnyRole('DOES NOT EVENT CHECK SYNTAX")
public Study findById(final Long id) {
return studyRepository.findOne(id);
}
}
测试成功,这是失败的。
答案 0 :(得分:0)
如果要测试Spring Security批注,则需要使用SpringRunner
来创建Spring Context并将Spring Security代码注入代理类。
如何测试Spring Security,您可以找到here。
答案 1 :(得分:0)
用
注释测试类@RunWith(SpringRunner.class)
@ContextConfiguration
您的方法应如下所示
@Test(expected = AccessDeniedException.class)
@WithAnonymousUser
@Test
public void findByIdWithoutAccessRightTest() {
Study study = studyService.findById(STUDY_ID);
}
您必须至少加载安全上下文才能测试安全性。
您可能想看一下这个例子:
public ApplicationUser getApplicationUser() {
ApplicationUser applicationUser = (ApplicationUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return applicationUser;
}
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.mock;
import org.mockito.MockitoAnnotations;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import com.arpit.security.user.ApplicationUser;
public class BaseTest {
@Before
public void setupMock() {
MockitoAnnotations.initMocks(this);
}
@Test
public void mockApplicationUser() {
ApplicationUser applicationUser = mock(ApplicationUser.class);
Authentication authentication = mock(Authentication.class);
SecurityContext securityContext = mock(SecurityContext.class);
when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);
when(SecurityContextHolder.getContext().getAuthentication().getPrincipal()).thenReturn(applicationUser);
}
}
来自:https://www.javacodegeeks.com/2017/05/mocking-spring-security-context-unit-testing.html
我想您的服务方法故意存在语法错误? (缺少括号和错误的引号?)
答案 2 :(得分:0)
这就是我的工作方式:
@RunWith(SpringRunner.class)
@SpringBootTest
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ActiveProfiles("test")
public class StudySecurityTest {
@Autowired
private StudyService service;
@MockBean
private StudyRepository repository;
@Test
@WithAnonymousUser
public void testAsAnonymous() {
...
}
@Test
@WithMockKeycloakUser(id = LOGGED_USER_ID, username = LOGGED_USER_USERNAME, authorities = { "ROLE_USER" })
public void testAsUser() {
...
}
}
如果您在@WithMockKeycloakUser
中被打扰了,问我。