Tuomas Kiviaho opened SPR-5292 and commented

SpringJUnit4ClassRunner is unaware of @Parameters annotation that normally is processed with JUnit's own Parameterized runner.


Affects: 2.5.6

Attachments: - ConstructorArgFromSpringConfigTestRunner.java (3.71 kB) - junit4_SpringParameterizedRunner.java (5.60 kB) - ParameterizedDirtiesContext.java (5.29 kB) - SpringJUnit4ParameterizedClassRunner.java (22.37 kB) - SpringJUnit4ParameterizedClassRunner.java.v2 (3.20 kB) - SpringParameterizedRunner.java (5.03 kB)

Issue Links: - #12387 Provide @Rule alternative to SpringJUnit4ClassRunner - #7791 Junit4 support

Referenced from: commits https://github.com/spring-projects/spring-framework-issues/commit/b9c8f104c6f2db8c8462334e1ccfa172932fd51e, https://github.com/spring-projects/spring-framework-issues/commit/239b3fe58d5cdeca374e2013993134eb3088327e

42 votes, 46 watchers

Comment From: spring-projects-issues

Jon Burgin commented

Here is our solution. Enjoy!

Comment From: spring-projects-issues

Jon Burgin commented

That is our solution is attached above. :)

Comment From: spring-projects-issues

Mark van der Voort commented

I think there are a few problems with the solution sketched. - It is not compatible with junit4.7 - Testcases will be treated as testclasses, so any class level DirtiesContext annotations will cause the the context to be refreshed after each case, rather than after the entire set

Comment From: spring-projects-issues

Matt Brown commented

Just curious - should the value of the Fix Version (which has been bumped from 3.0 RCs to 3.1 milestone) be interpreted as meaning that this support will be added in 3.1?

Comment From: spring-projects-issues

Juergen Hoeller commented

Indeed, we're usually setting the fix version as a kind of work plan. So in this case, the plan is indeed to provide this in 3.1 M2 towards the end of this year.

Juergen

Comment From: spring-projects-issues

Manjuka Soysa commented

As someone pointed out, the previous file does not work with the latest JUnit. The new SpringParameterizedRunner is hopefully useful for you until @Parameterized is officially supported by Spring.

Comment From: spring-projects-issues

Dave Syer commented

A better approach to this might be to provide the Spring integration test support as a @Rule (as well as or instead of a custom Runner). There might be some limitations of that approach, but it seems worth a try. I know Iwein did this in a blog a while ago, and although he didn't complete the feature set it was pretty easy to get off the ground.

Comment From: spring-projects-issues

Chris Beams commented

We ought to consider parameterization of profile combinations here as well. e.g.: run the same @Test with profiles [p1, p2] active, and run it again with [p2, p3] active, etc.

Comment From: spring-projects-issues

Josef Eisl commented

I've merged Springs JUnit4 Runner (3.0.4) with JUnits Parameterized Runner (r4.8.2). Working just fine for me but not extensively tested.

Comment From: spring-projects-issues

Marek Pietrasz commented

I am afraid current patch doesn't work with TestExecutionListener - I couldn't force it to execute beforeTestClass method.

Comment From: spring-projects-issues

Paris Holley commented

SpringJUnit4ParameterizedClassRunner.java currently has a createTest() implementation that instantiates a new instance of the test class for each method, is this intended behavior? I ended up changing it for our needs to only create it once (so that it behaves like normal non-parameterized tests).

Comment From: spring-projects-issues

Ryan Stewart commented

If I understand you correctly, that's not how JUnit behaves for non-parameterized tests. It always creates a new test instance for each test method. So yes, that's the intended behavior.

Comment From: spring-projects-issues

Paris Holley commented

Ryan you are right, taking another look at javadoc for Parameterized it says its a new instance per test, probably need to take issue up with JUnit. Such behavior makes maintaining test state harder, but can be worked around.

Comment From: spring-projects-issues

Chris Beams commented

Repro project at https://github.com/SpringSource/spring-framework-issues/pull/28. Thanks, Dave.

Comment From: spring-projects-issues

Flemming Jønsson commented

Hi Chris - I noticed your comment from a while back on this JIRA "We ought to consider parameterization of profile combinations here as well. e.g.: run the same @Test with profiles [p1, p2] active, and run it again with [p2, p3] active, etc."

I find that a very useful feature. It just so happens that we have a setup where we need this feature. So I did a small proof of concept using the SpringContextRule from https://github.com/SpringSource/spring-framework-issues/pull/28 and described my approach in the SpringSource fora.

It is very rough and it requires the use of the @Parameterized.Parameters array to supply the list of profiles per test iteration. However ugly an approach it may be it works fine and serves my purpose. So I thought that others might have a similar need and posted my approach here.

Feel free to criticize or suggest improvements. Next time I don't have anything to work on during my commute I will have a look at how to make this possible using the SpringJunit4 runner. http://forum.springsource.org/showthread.php?129462-RunWith(Parameterized-class)-with-different-set-of-Spring-profiles-per-parameter

Comment From: spring-projects-issues

Ib commented

None of the presently attached junit runners worked for me for one reason or another. As such, I wrote a runner that met my needs. I thought others might benefit from it, hence my sharing it here - by me attaching a file named SpringJUnit4ParameterizedClassRunner.java.v2

Comment From: spring-projects-issues

Gaetan Pitteloud commented

I just submitted the pull request 277 for this issue, in the form of a single runner that is able to run both parameterized and non-parameterized tests in the TestContext framework. I developed it some times ago and have been using it since then without any issue. The runner does not contain the spring-profile feature Chris Beams is talking about, but only "raw" parameterized tests.

Comment From: spring-projects-issues

Ruud Senden commented

It is not exactly a solution for the described problem, but the attached ConstructorArgFromSpringConfigTestRunner.java takes a different approach for parameterizing a unit test. Test classes will need to define a single constructor taking a single parameter. The runner will then run the test class once for every Spring bean that matches the constructor parameter type.

Please note that this class currently only performs dependency injection; for example it doesn't handle Spring Test annotations like ExpectedException, Repeat etc.

Comment From: spring-projects-issues

Ruud Senden commented

Run test once for each Spring bean that matches the single test constructor parameter type.

Comment From: spring-projects-issues

Nikolay Blindov commented

I have attached junit runner (a file namedParameterizedDirtiesContext.java) worked for me. My ruuner is inheritor of junit Parameterized ruuner and uses inheritor of SpringJUnit4ClassRunner for creation a test. So, the runner uses junit approach for parameterizing a unit test and support all SpringJUnit functionalites. The ruuner work with junit 4.8.2 and or higher version.

Comment From: spring-projects-issues

Marko Bjelac commented

I tried several runners attached here, but confirm that only [^SpringJUnit4ParameterizedClassRunner.java.v2] works for me.

Comment From: spring-projects-issues

Koen Serry commented

Since a pull request is created (and is confirmed to work), is there any reason not to merge it?

Comment From: spring-projects-issues

Sam Brannen commented

I am resolving this issue as essentially a duplicate of #12387, since #12387 introduced support for integrating the Spring TestContext Framework into JUnit via Rules instead of a Runner.

In other words, thanks to the support for rules introduced in #12387, there is no longer a need for a custom extension of SpringJUnit4ClassRunner that supports parameterized tests... since you can now simply use JUnit's Parameterized runner with Spring's rules.

See ParameterizedSpringRuleTests for a concrete example.