spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.75k stars 38.15k forks source link

Transactional testing with JMS #32499

Open djechelon opened 8 months ago

djechelon commented 8 months ago

I am working on a project heavily based on Spring Integration and JMS. One of the greatest deals with MockMvc is that you can wrap your data-driven test in a @Transactional annotation and have Spring revert your data back to the original state in order not to pollute data and fail subsequent tests.

Example

@SpringBootTest
@Transactional
@Sql
class MyDataDrivenTest {

    void doTest(){
        mockMvc.perform(...)
    }
}

The above code will populate data using an SQL file, the programmer can add as many JDBC/JPA changes before and during the test, and the Transaction will be rolled back at the end restoring the database.

The above cannot be applied in a JMS project. I'll provide a POC on demand, but it's pretty evident that with the following setup the JmsTemplate won't work as desired:

(see also)

If you start a transaction in the test, it will be pending during the execution of JMS interactions and since they occur in another thread, data written in the "main" transaction is not visible by the spawned transaction.

The idea is to discuss the opportunity to use a MockJms facility, inspired by MockMvc, that allows invoking JMS listeners (annotated or DSL-configured) from the same thread for testing purposes, in order to retain every desirable property of MockMvc. In my own case, I require transactionality.

Currently, I am adding a number of boilerplate components to handle cleanup, up to the point that I have to manually delete from the database the records I expect to have written after the test. This can be painful just up to the point you want to identify and list all records to remove (when you can't just truncate the related table).

I wanted to ask if this will be possible in the future, and if it is possible to start discussing it

jhoeller commented 8 months ago

On a related note, we are planning a broader revision of spring-jms in 6.2: see #32501, #26840, #22999.

While we may be able to address testability as well, I am not sure about how this will turn out. A fully-fleshed MockJms sounds rather tough to swallow but addressing transactional testing with JMS can certainly be a goal, one way or the other. I'll rephrase the scope of this issue accordingly.