Can't get custom annotation to work within test context using spring boot

179 views Asked by At

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.

0

There are 0 answers