Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Independent JUnit Tests with Springs @Autowired

As a beginner in Test Driven Development I just encountered a problem. My test class begins as follows:

@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@DirtiesContext
@ContextConfiguration(locations = {"/web-test.xml"})
public class XXTest {

  @Autowired
  XX xx;

  @Autowired
  HibernateTemplate template;

  @Test
  public void testSetGetXXValue() throws Exception {
    final Map<String, YY> profilMap = new HashMap<String, YY>(2);
    profilMap.put("1", new YY());
    profilMap.put("2", new YY());

    simpleCockpit.setValues(profilMap);

    assertEquals(profilMap, simpleCockpit.getValues());
  }

As you can see, the first test method alters the autowired XX-class. That affects all following test methods, which relies on XX having the autowired-values.

How can I test getter and setter from XX AND make sure XX has the autowired values for the rest of the test methods?

Thoughts:

  • Reset the right values at the end of test method. Bad because if the getter / setter are not working, this will also not work.
  • Place the first test method at the end of the test class. Bad because that makes the tests dependent on their execution order.
  • Do not test the getter / setter of XX. Bad because getter / setter have to be tested like every method.

Thanks for you answers! I`m pretty sure this has an easy solution ... :)

EDIT: Regarding the questions whether unit testing getters/setters or not, I decided to do so mainly because of the reasons statet at http://www.sundog.net/sunblog/posts/should-we-test-getters-and-setters/ .

like image 516
Steven Avatar asked Jul 21 '11 06:07

Steven


People also ask

Can we use Autowired in JUnit?

Also note that we can wire other spring beans in our jUnit test classes using @Autowired annotation.

Can we use Autowired in test class?

To check the Service class, we need to have an instance of the Service class created and available as a @Bean so that we can @Autowire it in our test class. We can achieve this configuration using the @TestConfiguration annotation.


1 Answers

If you modify an spring managed bean, then you could use the @DirtiesContext Annotation. This Annotation can be put on Test Classes as well as on Test Methods!

From @DirtiesContext Java Doc:

Test annotation which indicates that the {@link org.springframework.context.ApplicationContext ApplicationContext} associated with a test is dirty and should be closed:

  • after the current test, when declared at the method level
  • after each test method in the current test class, when declared at the class level with class mode set to {@link ClassMode#AFTER_EACH_TEST_METHOD AFTER_EACH_TEST_METHOD}
  • after the current test class, when declared at the class level with class mode set to {@link ClassMode#AFTER_CLASS AFTER_CLASS}

And even in Test Driven Development (to my understanding): write explicite tests only for stuff that has a minimum complexity. So I never write explicite tests for getter and setter. I normally have a test that checks some functionality, and when this functionality needs the getter and setter so I write this getter and setter (at this point in time) and that they works will be checked by the functionality I started with implicit.


Especially in your case: why do you use the Spring Bean, why not using "normal" Objects created with new. I use the "normal" classes as long as it is usefull for the tests, mostly for simple tests. I use Spring Beans for "bigger" tests as well.

like image 133
Ralph Avatar answered Sep 19 '22 22:09

Ralph