在 Spring Junit 测试中使用不同的 Auth 模型
Using different Auth mock up in Spring Junit tests
我正在使用 Spring 和 Junit4 来测试我的服务器应用程序。我的应用程序使用 Spring 安全性,一些查询利用 SpEL 语法来检查登录的用户。
因为我正在测试一些需要加载一些数据的场景,所以我遇到了一些问题,因为我不适合这样做。
例如:
@Test
@WithUserDetails(userDetailsServiceBeanName = "mockUserDetailService", value = "customer")
public void saveEcommerceTicket() {
ZonedDateTime entryDate = ZonedDateTime.now().plusDays(1);
createStandardFare();
createDailyCode(entryDate.toInstant());
createPaymentWithWallet();
Customer customer = createCustomerWithWallet(new BigDecimal(100));
Ticket ticket = new Ticket();
ticket.setLicensePlate1("AA123BB");
ticket.setArea(areaCentroStorico);
ticket.setDailyCode("CC");
ticket.setEntryDate(entryDate.toInstant());
ticket.setExitDate(entryDate.plusDays(1).toInstant());
ticket.setPassengers(50);
ticket.setPassengersCountry(italy);
ticket.setCustomer(customer);
ticket = ticketService.saveFromEcommerceWithWalletPayment(ticket, new ArrayList<Media>());
assertEquals(true, ticket.isStandard());
assertEquals(TicketStatus.VALID, ticket.getStatus());
assertTrue(new BigDecimal(100).compareTo(ticketRepository.sumPayments(ticket.getId())) == 0);
assertTrue(BigDecimal.ZERO.compareTo(customer.getWallet().getBalance()) == 0);
assertEquals(true, ticket.isPaid());
}
这是我使用自定义 userdetailservice 的测试示例。不幸的是,一些操作,如:createStandardFare()、createDailyCode() 等,需要不同的角色。
我尝试设置手动身份验证,但我最终总是用一个角色完成整个测试。相反,我需要一些部分以特定的角色(比如说 ADMIN)执行,而另一些部分以另一个角色(比如说 CUSTOMER)执行。
有没有办法用 Spring 和 Junit 来完成这个?
如果您在需要不同角色的单个测试方法中调用不同的方法,您实际上只有两个选择。
- 配置一个模拟用户(例如,通过
@WithMockUser
或类似的方式)分配测试方法中使用的所有角色。
- 在测试方法本身内以编程方式切换当前模拟用户。
- 例如,使用以下代码片段。
@Test
public void test() {
login("customer", "password", "ROLE_CUSTOMER");
// ...
login("admin", "password", "ROLE_ADMIN");
// ...
}
static void login(String username, String password, String... roles) {
SecurityContext context = SecurityContextHolder.createEmptyContext();
User user = new User(username, password, roles(roles));
Authentication auth = new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities());
context.setAuthentication(auth);
SecurityContextHolder.setContext(context);
}
static List<SimpleGrantedAuthority> roles(String... roles) {
return Arrays.stream(roles).map(SimpleGrantedAuthority::new).collect(toList());
}
注:上例中的User
为org.springframework.security.core.userdetails.User
.
我正在使用 Spring 和 Junit4 来测试我的服务器应用程序。我的应用程序使用 Spring 安全性,一些查询利用 SpEL 语法来检查登录的用户。
因为我正在测试一些需要加载一些数据的场景,所以我遇到了一些问题,因为我不适合这样做。
例如:
@Test
@WithUserDetails(userDetailsServiceBeanName = "mockUserDetailService", value = "customer")
public void saveEcommerceTicket() {
ZonedDateTime entryDate = ZonedDateTime.now().plusDays(1);
createStandardFare();
createDailyCode(entryDate.toInstant());
createPaymentWithWallet();
Customer customer = createCustomerWithWallet(new BigDecimal(100));
Ticket ticket = new Ticket();
ticket.setLicensePlate1("AA123BB");
ticket.setArea(areaCentroStorico);
ticket.setDailyCode("CC");
ticket.setEntryDate(entryDate.toInstant());
ticket.setExitDate(entryDate.plusDays(1).toInstant());
ticket.setPassengers(50);
ticket.setPassengersCountry(italy);
ticket.setCustomer(customer);
ticket = ticketService.saveFromEcommerceWithWalletPayment(ticket, new ArrayList<Media>());
assertEquals(true, ticket.isStandard());
assertEquals(TicketStatus.VALID, ticket.getStatus());
assertTrue(new BigDecimal(100).compareTo(ticketRepository.sumPayments(ticket.getId())) == 0);
assertTrue(BigDecimal.ZERO.compareTo(customer.getWallet().getBalance()) == 0);
assertEquals(true, ticket.isPaid());
}
这是我使用自定义 userdetailservice 的测试示例。不幸的是,一些操作,如:createStandardFare()、createDailyCode() 等,需要不同的角色。 我尝试设置手动身份验证,但我最终总是用一个角色完成整个测试。相反,我需要一些部分以特定的角色(比如说 ADMIN)执行,而另一些部分以另一个角色(比如说 CUSTOMER)执行。
有没有办法用 Spring 和 Junit 来完成这个?
如果您在需要不同角色的单个测试方法中调用不同的方法,您实际上只有两个选择。
- 配置一个模拟用户(例如,通过
@WithMockUser
或类似的方式)分配测试方法中使用的所有角色。 - 在测试方法本身内以编程方式切换当前模拟用户。
- 例如,使用以下代码片段。
@Test
public void test() {
login("customer", "password", "ROLE_CUSTOMER");
// ...
login("admin", "password", "ROLE_ADMIN");
// ...
}
static void login(String username, String password, String... roles) {
SecurityContext context = SecurityContextHolder.createEmptyContext();
User user = new User(username, password, roles(roles));
Authentication auth = new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities());
context.setAuthentication(auth);
SecurityContextHolder.setContext(context);
}
static List<SimpleGrantedAuthority> roles(String... roles) {
return Arrays.stream(roles).map(SimpleGrantedAuthority::new).collect(toList());
}
注:上例中的User
为org.springframework.security.core.userdetails.User
.