Для меня этот вид теста - это запах кода.Вопрос всегда в том, что точно этот тест проверяет?В этом тесте, чему вы доверяете и чему не доверяете?
Для меня вы не можете доверять read () и write () вместе, они, вероятно, находятся в одном классе, написанномтот же человек.Так что, если вы тестируете read () с помощью вызова write (), тогда это не очень хороший тест, вы тестируете, что write () и read () синхронизированы, а не то, что они должны делать.
Во втором примере вы проверяете, что копирование и равенство синхронизированы, та же проблема.
Допустим, это была реализация уровня персистентности:
public class PersistenceLayer {
private Object object;
void write(Object object) {
this.object = object;
}
Object read(Long id) {
return object;
}
}
Вопрос в том, пройдут ли ваши тесты с этим постоянным слоем?Но он явно не делает то, что вы хотите.Это не идет рядом с базой данных.Аналогичным образом, пройдут ли ваши тесты, если ваши операции чтения и записи будут разделять сеанс / транзакцию?В этом случае данные никогда не будут фактически переданы в базу данных.Это может сделать откат в конце.Но ваши тесты все равно пройдут.
Читая ваше описание, вы проверяете, что когда я вызываю write () и затем read (), я получаю похожий объект обратно.То, что я ожидал бы от метода write (), это то, что он записывает данные в базу данных.Поэтому, если я проверяю , что , мне нужно это проверить.Поэтому у меня должен быть другой канал, который я могу использовать для проверки чтения и записи.Обычно это заканчивается созданием нового Соединения через JDBC и выполнением выбора.
Таким образом, мой код тестирования будет
testWrite() {
write(o);
Object o2 = readByJdbc("SELECT * FROM table WHERE id = ?", o);
assertObjectsEqual(o, o2); // this needs to compare all values
}
testRead() {
write(o);
Object o2 = read(o.id);
Object o3 = readByJdbc("SELECT * FROM table WHERE id = ?", o);
assertObjectsEqual(o2, o3); // this needs to compare all values
}
testWrite () записывает в базу данных и гарантирует, что данныезаписывается в базу данных путем открытия соединения JDBC и чтения таким образом (другой сеанс, другая транзакция, т.е. данные будут в базе данных).
testRead () записывает в базу данных и сравнивает два объекта, возвращенныечитать через слой постоянства и через JDBC.Я дублирую вызов write (o), но это приемлемо, потому что мы знаем, сработает ли write при вызове другого теста.Я мог бы написать другой writeByJdbc, но все, что я получил бы, это то, что один тест провалится вместо двух.
Фактически, в зависимости от вашего уровня паранойи, вам не нужно сравнивать все значения в assertObjectsEqual ().Если вы, например, используете hibernate, вы можете просто предположить, что все объявлено правильно, и проверить наличие строки в базе данных.Я делаю это часто, потому что я верю в спящий режим.Но в этом случае мне нужно проверить, как я называю hibernate, как определяются объекты.
Код jdbc не должен быть длинным и сложным, для простого выбора я просто создаю списокОтображение столбцов в значения:
private List<Map<String, Object>> resultSetToListMap(ResultSet resultSet) throws SQLException {
int columnCount = resultSet.getMetaData().getColumnCount();
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
while (resultSet.next()) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
for (int i = 1; i <= columnCount; i++) {
map.put(resultSet.getMetaData().getColumnName(i), resultSet.getObject(i));
}
list.add(map);
}
return list;
}
Этого более чем достаточно для большинства тестов.