在Spring Junit测试中使用不同的Auth模拟

时间:2018-03-13 17:54:02

标签: java spring junit spring-test

我使用Spring和Junit4来测试我的服务器应用程序。我的应用程序使用Spring Security,一些查询利用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()等需要不同的角色。 我试图设置手动身份验证,但我最终总是用一个ROLE进行整个测试。相反,我需要使用特定的ROLE执行某些部分(让我们说管理员),而另一些部分执行另一部分(让他们说CUSTOMER)。

有没有办法用Spring和Junit来实现这个目标?

1 个答案:

答案 0 :(得分:0)

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

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