Most of my tests have the same configuration, I would like to have my own to reduce repetetion.
When I use complete list of annotation the test application context starts up as expected.
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@ActiveProfiles("dev")
public class UserRepositoryTest {
@Autowired
UserRepository userRepository;
@Test
public void testSave(){
final User user = new User("test","[email protected]","test");
userRepository.save(user);
User retrievedUser = userRepository.findUserByUsername("test");
assertNotNull(retrievedUser);
assertEquals("test", retrievedUser.getUsername());
}
}
Now suppose I define my own custom annotation to include all of class annotations in simillar style as @SpringBootApplication
.
So I create:
import com.company.Application;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@ActiveProfiles("dev")
public @interface TestContext {
}
Looks beautiful and lazy as I want :-)
@TestContext
public class UserRepositoryTest {
@Autowired
UserRepository userRepository;
@Test
public void testSave(){
final User user = new User("test","[email protected]","test");
userRepository.save(user);
User retrievedUser = userRepository.findUserByUsername("test");
assertNotNull(retrievedUser);
assertEquals("test", retrievedUser.getUsername());
}
}
When I run my test with new annotation I get:
java.lang.NullPointerException
at com.company.repository.UserRepositoryTest.testSave(UserRepositoryTest.java:33)
as userRepository
is not @Autowired
and the application context is not even started. The log is not particularly helpful.
I am sure I am missing something really trivial or doing something terribly stupid.
Update: It feels like the only annotation I cannot extract out is:
@RunWith(SpringJUnit4ClassRunner.class)
I seem to be able to extract the last 4:
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@ActiveProfiles("dev")
Update 2 Solution: Nothing to do with Spring.
The solution can be found: Java annotations - code simplifications. The only way to extract Junit annotation is by normal class inheritance otherwise keep it separate(so @TestContext
+ @RunWith(SpringJUnit4ClassRunner.class)
). I am marking this as duplicate.