Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why @RunWith(SpringJUnit4ClassRunner.class) doesn't work?

Tags:

junit

spring

I am trying to test CRUD methods with JUnit using Spring framework. The code below works perfectly

 @Transactional
public class TestJdbcDaoImpl {
    @SuppressWarnings("deprecation")
    @BeforeClass 
    @Test
    public static void setUpBeforeClass() throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
        JdbcDaoImpl dao = ctx.getBean("jdbcDaoImpl",JdbcDaoImpl.class);
        Circle cicle = new Circle();
        dao.insertCircle(new Circle(6,"e"));
    }}

However, following code with @RunWith(SpringJUnit4ClassRunner.class) gives me an error

**Jun 11, 2014 1:00:15 PM org.springframework.test.context.TestContextManager retrieveTestExecutionListeners INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext] **

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring.xml")
@Transactional
public class TestJdbcDaoImpl {

   @Autowired
   private static JdbcDaoImpl dao;

   @SuppressWarnings("deprecation")
   @BeforeClass 
   public static void setUpBeforeClass() throws Exception {
       Circle cicle = new Circle();
       dao.insertCircle(new Circle(10,"e"));
   }
like image 771
Aidos Askhatuly Avatar asked Jun 11 '14 06:06

Aidos Askhatuly


3 Answers

There are at least two problems in your test

  • 1) You can not use the standard ServletContext in a test. Either you use a part of the Spring configuration that only uses Beans that not use the ServletContext, or you use the Spring-MVC-Test support (available since Spring 3.2)

  • 2) @BeforeClass run before the spring context ins loaded. Therefore use @Before instead.

Example that try to fix both problems:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration                      // <-- enable WebApp Test Support
@ContextConfiguration("/spring.xml")
@Transactional
public class TestJdbcDaoImpl {

   @Autowired
   private static JdbcDaoImpl dao;

   @SuppressWarnings("deprecation")
   @Before                               // <-- Before instead of BeforeClass
   public static void setUpBeforeClass() throws Exception {
       Circle cicle = new Circle();
       dao.insertCircle(new Circle(10,"e"));
   }
like image 123
Ralph Avatar answered Sep 28 '22 16:09

Ralph


WebAppConfiguration should only be used if you want to load a WebApplicationContext. In case of a simple unit test (i.e. not an integration test), you should not rely on this annotation.

The error message is pretty clear: either specify custom listener classes or make the default listener classes (and their required dependencies) available. In other words, either specify the following:

@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class })

as defined in org.springframework.test.context.TestContextManager:

    private static final String[] DEFAULT_TEST_EXECUTION_LISTENER_CLASS_NAMES = new String[] {
        "org.springframework.test.context.web.ServletTestExecutionListener",
        "org.springframework.test.context.support.DependencyInjectionTestExecutionListener",
        "org.springframework.test.context.support.DirtiesContextTestExecutionListener",
        "org.springframework.test.context.transaction.TransactionalTestExecutionListener" };

so that ServletTestExecutionListener is not loaded anymore, or add the following dependency: javax.servlet-api

like image 23
Jean-Christophe Avatar answered Sep 28 '22 16:09

Jean-Christophe


I had this problem, and the @TestExecutionListener suggestion didn't work for me. I then updated my junit dependency (4.8.2->4.12), and that resolved the issue.

like image 42
NielsR Avatar answered Sep 28 '22 15:09

NielsR