使用 EntityManager 进行 Spring Boot 和安全集成测试

Posted

技术标签:

【中文标题】使用 EntityManager 进行 Spring Boot 和安全集成测试【英文标题】:Spring boot and Security Integration test with EntityManager 【发布时间】:2017-03-17 01:30:36 【问题描述】:

我想测试我的 Spring 应用程序。它需要身份验证,因此我创建了一个用户对象并将其保存在@Before 方法中。但我无法进行身份验证,因为我认为init() 方法是在另一个会话中执行的。

IntegrationTest类:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
public class IntegrationTest 

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @LocalServerPort
    int port;

    private String URL;

    @Before
    public void init() 
        User user = new User();
        user.setUsername("testUser");
        user.setPassword(passwordEncoder.encode("test"));
        user.setEmail("test@test.com");
        user.setEnabled(true);
        entityManager.persist(user);
        entityManager.flush();
        entityManager.clear();

        RestAssured.port = port;

        URL = "http://localhost:" + String.valueOf(port) + "/users/user";
    

    @Test
    public void givenNotAuthenticatedUser_whenLoggingIn_thenCorrect() 
        final RequestSpecification request = RestAssured.given().auth().basic("testUser", "test");

        request.when().get(URL).then().assertThat().statusCode(200);
    

但是如果我使用我的userRepository 并打电话

userRepository.save(user);

而不是

entityManager.persist(user);
entityManager.flush();
entityManager.clear();

一切正常。我还必须删除@Transactional 注释。

首先我认为这是因为没有提交 - 我看到用户表中没有任何更改。如何强制EntityManager 提交数据?

如何在测试中使用EntityManager?为什么UserRepository 运行良好?

【问题讨论】:

【参考方案1】:

如documentation中所述:

默认情况下,框架会为每个测试创建和回滚一个事务。

您可以在您的测试类上使用@Commit 覆盖它,并将TestTransaction.end() 放在entityManager.clear() 之后。

现在测试工作正常,但我仍然无法理解 UserRepository 在不提交事务的情况下为什么以及如何工作。

【讨论】:

为什么要投反对票?我的问题分为三个部分,这是“如何强制 EntityManager 提交数据?”的答案。

以上是关于使用 EntityManager 进行 Spring Boot 和安全集成测试的主要内容,如果未能解决你的问题,请参考以下文章

使用 EntityManager / Hibernate 进行批量更新

使用 EntityManager 进行 Spring Boot 和安全集成测试

使用 JPA EntityManager 进行批量插入

使用SpringDataJpa和Hibernate / eclipselink时entityManager的行为

使用 HikariCP 时在每次 db 操作后关闭 EntityManager

TransactionRequiredException:没有用于当前线程的具有实际事务的EntityManager-无法可靠地处理“合并”调用