Reputation: 14666
I'm trying to test a class in a Spring project. I would like to make as many changes as possible in the test class vs. the dao class so that I don't have to retest all sorts things because of a change.
The class I'm working with has a JdbcTemplate template
class variable that is instantiated by the following:
setJdbcTemplate(DataSource dataSource) {
this.template = new JdbcTemplate(dataSource);
}
The method I would like to test makes a template.query(<code>)
to run a defined SQL query and return the results to a list.
I created the following in my test case, but I'm not sure how to put it into use. Can I make the following code return a certain list of Strings using Mockito?
DataSource mockedDataSrc = Mockito.mock(DataSource.class);
customerClassDao.setJdbcTemplate(mockedDataSrc);
Can I somehow use the when
or another command to set what I want to be returned to the JdbcTemplate's .query
call?
Upvotes: 4
Views: 47746
Reputation: 308733
If you're testing a DAO it makes no sense at all to mock the data source. What are you testing? You need to make a DAO that interacts with the database.
Once you have that working, you're free to mock the interface-based DAO when testing services that use it. You've already tested the DAO; there's no reason to redo it when testing the services.
I'd say you're off-track if you're mocking the data source when testing the DAO.
Upvotes: 4
Reputation: 67300
You can't do this because you don't have control over the JdbcTemplate
implementation. You should dependency inject the JdbcTemplate
and then mock the JdbcTemplate
instead.
This difficulty is pointing out a problem with your code. Your code depends on the concrete instance of JdbcTemplate
. It would be less coupled if you used Dependency Injection on it instead.
Since you don't want to modify your system under test, you can do this:
Change the template
field so it's package protected (ie: remove the private keyword). Then, I'd set it to be a mock(JdbcTemplate.class) after you instantiate the class you're testing. Now you'll be able to use when and verify on the JdbcTemplate directly like you wanted originally.
So the class you're testing will look like this:
public class SystemUnderTest {
JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(DataSource dataSource) {
this.template = new JdbcTemplate(dataSource);
}
}
And your test will do this:
@Before
public void setUp() {
SystemUnderTest sut = new SystemUnderTest();
sut.jdbcTemplate = mock(JdbcTemplate.class);
}
// ...
Upvotes: 4