Reputation: 265
I want to implement a database reader using Spring and JDBC.
@Component
public class MyReader() {
public void read() {
/* Other code */
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
String myDbValue = rs.getString("myColumn");
}
/* Other code */
}
}
I want to test the behavior of my class, if column myColumn
isn't present.
One solution would be to move the constant myColumn
to a private method, but some guys on SO told other users, that mocking private methods smells, see Raedwalds comment and I would agree.
I could also mock the database file itself, but mocking files isn't a good way too.
Any ideas how handle this issue?
Upvotes: 1
Views: 2203
Reputation: 18233
Your test code, and therefore what/how you choose to mock, is intrinsically and inextricably linked to the functionality of the method you're testing. Now, this doesn't mean that it should be tied to the implementation of that method (you want to keep this fairly decoupled), but the core purpose of what the method aims to do is what you should be testing. This is why well-designed, well thought out tests drives good API design.
The question you therefore need to ask yourself is What is the read
method doing?.
I suspect that both the Statement
and the ResultSet
returned from executing the query are implementation details that you can mock out for the purposes of your test.
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.mockito.Matchers.*;
import java.sql.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class MyReaderTest {
@InjectMocks
private MyReader myReader;
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
Statement s = mock(Statement.class);
ResultSet rs = mock(ResultSet.class);
when(s.executeQuery(anyString())).thenReturn(rs);
when(rs.getString("myColumn")).thenThrow(SQLException.class);
}
@Test
public void testRead_AccessNonExistentColumn() {
// Use mock statement and mock resultset
}
}
Upvotes: 3