Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create and use a Custom Annotation having Spring+JUnit Test Config annotations?

I have large number of test cases which runs with Spring Junit Support with following annotations on each Test.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring/applicationContext.xml")
@TransactionConfiguration(transactionManager="transactionManager")
@Transactional
@ActiveProfiles("test")

Instead of putting all these annotations on each Test class I want to Create a Custom Annotation and use it.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring/applicationContext.xml")
@TransactionConfiguration(transactionManager="transactionManager")
@Transactional
@ActiveProfiles("test")

@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SpringJUnit4TestConfig {

}

But when I use this Custom Annotation Spring Injection is not happening at all.

@SpringJUnit4TestConfig
public class UserServiceTest
{
}

What I am missing here?

PS: But JUnit's @RunWith and Spring's @Transactional, @ContextConfiguration all have @Inherited..So I thought it should work. But for now I get through it through a work around. Created a Based Abstract class and put all those Annotations on it and the test cases extending that Base class.

like image 560
K. Siva Prasad Reddy Avatar asked Sep 23 '12 13:09

K. Siva Prasad Reddy


People also ask

How do you write a test case for custom annotations?

Custom annotation with its Aspect There are two approaches you take here; The unit testing approach: Unit test the methodTimeLogger method of the MethodTimeLogger class. Then write a method that uses the @MethodTimeLogger annotation. In another test, check if the methodTimeLogger method was called by spying on it.


1 Answers

I don't think that this approach will work, as @RunWith is JUnit annotation, so for this to work JUnit annotations must be transitive.

When a class is annotated with @RunWith or extends a class annotated with @RunWith, JUnit will invoke the class it references to run the tests in that class instead of the runner built into JUnit. We added this feature late in development. While it seems powerful we expect the runner API to change as we learn how people really use it. Some of the classes that are currently internal will likely be refined and become public.

So test JUnit test invoking seem to work only for the inherited classes.

As for Spring, it supports a thing called context configuration inheritance for configuration locations, I'm quite not sure that this should work for other annotations types (please point me to the documentation, if you think otherwise) Actually, this will likely work for other annotations in case of test configuration class inheritance because @Transactional annotation itself is declared with @Inherited for this case.

So in this case, it does not run because of JUnit annotation's missing.

like image 165
Boris Treukhov Avatar answered Oct 27 '22 23:10

Boris Treukhov