I recently cam across a class like this:
public class SomeDao {
@Inject
private DataSource dataSource;
@Value("#{someMap['someDao.sql']}")
private String sql;
private JdbcTemplate jdbcTemplate;
@PostConstruct
private void postConstruct() {
jdbcTemplate = new JdbcTemplate(dataSource);
}
...
}
Now I would like to unit test this class by injecting the DataSource and the SQL string. As far as I can see, there are two options for this:
In the days before spring annotations, the class would have been written like this:
public class SomeDao {
private String sql;
private JdbcTemplate jdbcTemplate;
public SomeDao(DataSource dataSource, String sql) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.sql = sql;
}
...
}
And I could have easily tested this class without the need for reflection or spring. My class was a pure pojo and had no spring dependencies.
So, are spring annotations a good thing or are they a step backwards? Are there times where I shoulud be using them and times when I should use the old XML app context?
Thanks, Lance.
Why not declare a test-context with mocks of beans and inject those needed by your class from that? That's what people usually do and it's quite straightforward.
The most lightweight way of doing this is to provide an inner class inside your test class, annotated with @Configuration
that has methods that provide mocks:
@Configuration
public class DataAccessConfiguration {
@Bean
public DataSource dataSource() {
DataSource dataSource = mock(Datasource.class);
return dataSource;
}
@Bean
public Map<String,String> someMap() {
Map<String, String> map = new HashMap<>();
map.put("someDao.sql", "somevalue");
return map;
}
}
So instead of giving up on autowiring, you can actually take advantage of it. Also you limit the loaded context to just what is needed by the class under test.