Skip to content

Support @Transactional on TestNG @BeforeClass methods in the TestContext framework [SPR-11397] #16024

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Feb 5, 2014 · 6 comments
Assignees
Labels
in: test Issues in the test module status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Feb 5, 2014

Adib Saikali opened SPR-11397 and commented

When using the Spring TestContext Framework with TestNG it is not possible to annotate a TestNG @BeforeClass method with @Transactional and have it executed with a Spring-managed transaction, as depicted in the example below.

@ContextConfiguration("/test.xml")
public class TransactionalTest extends AbstractTransactionalTestNGSpringContextTests {

    @BeforeClass
    @Transactional
    public void setupDB() {
        // the following assert fails because there is no active transaction.
        assertThat(TransactionSynchronizationManager.isActualTransactionActive()).isTrue(); 
        // do some stuff that needs a tx
    }
}

With the current implementation of AbstractTransactionalTestNGSpringContextTests it is possible to refer to any autowired variable within an @BeforeClass method. It seems that by the the time @BeforeClass method is invoked Spring is fully initialized and therefore any @Transactional method should be working. It feels counter-intuitive that @Transactional and @BeforeClass in TestNG don't work with each other. As an aside, I understand why JUnit's @BeforeClass does not work with @Transactional.

One of the primary reasons for using TestNG over JUnit is that TestNG makes writing integration tests easier because of the way @BeforeClass works in TestNG. So in many integration testing scenarios it is possible that an @BeforeMethod method needs to read data from JPA or do some other prep work for the test that is @Transactional.

Can you please make @BeforeClass and @Transactional work together for TestNG?

In the meantime I have sent a pull request on GitHub to update the docs so that they at least warn users that @BeforeClass and @Transactional don't work with each other.


Affects: 3.0 GA

Issue Links:

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Hi Adib,

Thanks for taking the time to submit such a detailed issue and for submitting the pull request. I will take a look at your recommendations there.

Regarding your question:

Can you please make @BeforeClass and @Transactional work together for TestNG?

The issue here is that @Transactional is only supported for test methods. This is by design and therefore cannot be changed. Changing this fundamental feature would break existing code bases.

Now, having said that, all is not lost in your case...

The support for managing transactions for tests is governed by the beforeTestMethod() and afterTestMethod() methods in TransactionalTestExecutionListener. This will not change; however, you can change when these two methods are invoked. As the names imply, they are intended to be executed before and after @Test methods, but if you would like them to execute before @BeforeClass and after @AfterClass methods, this should be possible with TestNG (but not with JUnit).

Consider the following note from the "Testing" chapter of the reference manual (see the TestNG support classes section).

These classes are a convenience for extension. If you do not want your test classes to be tied to a Spring-specific class hierarchy — for example, if you want to directly extend the class you are testing — you can configure your own custom test classes by using @ContextConfiguration, @TestExecutionListeners, and so on, and by manually instrumenting your test class with a TestContextManager. See the source code of AbstractTestNGSpringContextTests for an example of how to instrument your test class.

In other words, you do not have to extend AbstractTestNGSpringContextTests or AbstractTransactionalTestNGSpringContextTests when working with TestNG. You are free to implement your own test class from scratch and invoke the corresponding methods of TestContextManager wherever you choose. Of course the order in which you invoke methods on TestContextManager should make logical sense, but otherwise it's up to you.

The default implementation of AbstractTestNGSpringContextTests is provided just for convenience, since it suits the needs of most developers, but you can make your own version that utilizes different TestNG annotations to instrument the test lifecycle as you see fit.

Give it a try!

Regards,

Sam

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Feb 6, 2014

Sam Brannen commented

Resolving this issue as Works as Designed.

See previous comments for details.

Also, please note that the requested documentation enhancement is now covered in #16026.

@spring-projects-issues
Copy link
Collaborator Author

Adib Saikali commented

Thanks for clarifying the options, I will try making my own base class, that behaves the way I want.

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Hi Adib,

Please let us know if that works out for you, especially since other developers might be interested in your solution.

Thanks,

Sam

@spring-projects-issues
Copy link
Collaborator Author

Giovanni commented

Good morning, I'd like to know if this issue has been resolved, or if there is anything I can do to resolve it.

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Yes, this issue was resolved as Works as Designed on February 6, 2014.

Please see the above comments.

I am now closing this issue permanently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test Issues in the test module status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants