在 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 来完成这个?

如果您在需要不同角色的单个测试方法中调用不同的方法,您实际上只有两个选择。

  1. 配置一个模拟用户(例如,通过 @WithMockUser 或类似的方式)分配测试方法中使用的所有角色。
  2. 在测试方法本身内以编程方式切换当前模拟用户。
    • 例如,使用以下代码片段。
@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());
}

注:上例中的Userorg.springframework.security.core.userdetails.User.