Как модульно протестировать DAO, расширяющий SqlMapClientDaoSupport
Вопрос
Spring DA помогает в написании DAO.При использовании iBatis в качестве платформы сохранения и расширении SqlMapClientDaoSupport для DAO должен быть установлен макет SqlMapClient, но я не могу этого сделать.SqlMapClientTemplate не является интерфейсом, и EasyMock не может создать для него макет.
Решение
DAO и модульные тесты плохо уживаются !Нет смысла издеваться над чем-либо в компоненте, который не содержит никакой бизнес-логики и ориентирован на доступ к базе данных.Вместо этого вам следует попробовать написать интеграционный тест.Взгляните на справочную документацию spring, глава 8.3 : http://static.springframework.org/spring/docs/2.5.x/reference/testing.html
Другие советы
Именно по этой причине я не распространяюсь на SqlMapClientDaoSupport
.Вместо этого я ввожу зависимость в SqlMapClientTemplate
(вводится как интерфейс SqlMapClientOperations
).Вот пример Spring 2.5:
@Component
public class MyDaoImpl implements MyDao {
@Autowired
public SqlMapClientOperations template;
public void myDaoMethod(BigInteger id) {
int rowcount = template.update("ibatisOperationName", id);
}
}
Как предложил @Banengusk - этого можно достичь с помощью Мокито.Однако важно установить, что ваш DAO будет использовать Spring SqlMapClientTemplate
это оборачивает ваш макет SqlMapClient
.Воздействовать, SqlMapClientTemplate
делегирует обращения к SqlMapSession
в слое ибатиса.
Поэтому требуется некоторая дополнительная настройка макета:
mockSqlMapSession = mock(SqlMapSession.class);
mockDataSource = mock(DataSource.class);
mockSqlMapClient = mock(SqlMapClient.class);
when(mockSqlMapClient.openSession()).thenReturn(mockSqlMapSession);
when(mockSqlMapClient.getDataSource()).thenReturn(mockDataSource);
dao = new MyDao();
dao.setSqlMapClient(mockSqlMapClient);
Затем мы можем проверить поведение следующим образом:
Entity entity = new EntityImpl(4, "someField");
dao.save(entity);
ArgumentCaptor<Map> params = ArgumentCaptor.forClass(Map.class);
verify(mockSqlMapSession).insert(eq("insertEntity"), params.capture());
assertEquals(3, params.getValue().size());
assertEquals(Integer.valueOf(4), params.getValue().get("id"));
assertEquals("someField", params.getValue().get("name"));
assertNull(params.getValue().get("message"));
Попробуй Мокито.Это позволяет имитировать классы, а не только интерфейсы.