【发布时间】:2016-10-17 09:25:44
【问题描述】:
我正在使用:
request.IsUserInRole("ADMIN")
在我的一个控制器中确定对请求的响应。我试图在我的测试中模拟请求,例如:
@Mock
private HttpServletRequest httpRequest;
并使用 Springs 注释 @WithMockUser:
@Test
@WithMockUser(roles={"USER, ADMIN"})
public void getAccountsTest() throws Exception {...}
两者都不起作用。
问题 1:如何在 JUnit 测试中模拟 request.IsUserInRole("ADMIN")?
问题2:@WithMockUser对请求和request.IsUserInRole("ADMIN")有什么影响?
感谢和问候
----编辑----
“没用”表示我有测试方法:
@Test
@WithMockUser(username = "user", roles={"USER"})
public void getAccountsReturnForbiddenTest() throws Exception {
mockMvc.perform(get("/accounts/"))
.andExpect(status().isForbidden());
}
应该返回 403,因为控制器不允许:
@RequestMapping(method=RequestMethod.GET)
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<PagedResources<AccountResource>> getAccounts(...){...}
但是请求返回200,OK。
我使用的是 Spring Boot 1.4.1。
---- 编辑 2 ----
我的 JUnit 测试类:
@Transactional
@ContextConfiguration
public class AccountControllerTestDoc extends AbstractControllerTest {
@InjectMocks
private AccountController accountController;
@Mock
private AccountService accountService;
private String uriBase = "";
@Before
public void setup() {
// Initialize Mockito annotated components
MockitoAnnotations.initMocks(this);
// Prepare the Spring MVC Mock components for standalone testing
setup(accountController);
}
@Test
@WithMockUser(username = "user", roles={"USER"})
public void getAccountsReturnForbiddenTest() throws Exception {
String uri = uriBase + "/accounts";
mockMvc.perform(get(uri))
.andExpect(status().isForbidden());
}
}
使用 AbstractControllerTest:
@WebAppConfiguration
public abstract class AbstractControllerTest extends AbstractTest {
protected MockMvc mockMvc;
@Autowired
protected WebApplicationContext wac;
protected void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
protected void setup(BaseController controller) {
mockMvc = MockMvcBuilders.standaloneSetup(controller))
.build();
}
}
和 AbstractTest:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public abstract class AbstractTest {
protected Logger LOG = LoggerFactory.getLogger(this.getClass());
}
----解决方案----
MockMvc standaloneSetup 不知道 Web 应用程序上下文,因此不知道安全过滤器链。必须使用 Web 应用程序上下文和安全过滤器链设置 MockMvc 才能测试安全方面。
这是我现在工作的解决方案,我编辑了 AbstractControllerTest:
@WebAppConfiguration
public abstract class AbstractControllerTest extends AbstractTest {
protected MockMvc mockMvc;
@Autowired
protected WebApplicationContext wac;
@Autowired
FilterChainProxy springSecurityFilterChain;
protected void setup() {
mockMvc = MockMvcBuilders
.webAppContextSetup(wac)
.addFilters(springSecurityFilterChain)
.build();
}
protected void setup(BaseController controller) {
mockMvc = MockMvcBuilders.standaloneSetup(controller))
.build();
}
}
【问题讨论】:
-
“没用”的意思是……
-
对不起,“没用”意味着我在没有管理员角色的安全方法上运行 get 请求,返回状态不是预期的 403(未授权)而是 200(正常) .
-
请说明您是如何设置
mockMvc的。 -
我有一个类似的案例,这对我有用stackoverflow.com/a/32777599/4614788
标签: java spring spring-mvc mockito