Правильный подход к тестированию класса, не имеющего конструктора по умолчанию?

#java #unit-testing #testing #junit #refactoring

#java #модульное тестирование #тестирование #junit #рефакторинг

Вопрос:

Ниже DBMetaData приведен класс, зависящий от TableData :

 import javax.sql.DataSource;    
import java.util.HashMap;
import java.util.Map;

public class DBMetaData {

    private DataSource dataSource;
    private Map<String, TableData> tables;
    private static final String[] TYPES = {"TABLE", "VIEW"};

    public DBMetaData(DataSource dataSource) {
        this.dataSource = dataSource;
        this.tables = new HashMap<String, TableData>();
    }
.......

}


public class TableData {
    private String name;
    private Map<String, ColumnData> columns = new HashMap<String, ColumnData>();
    private String catalog;
    private String schema; 

    TableData(ResultSet rs, DatabaseMetaData meta) throws SQLException {
    catalog = rs.getString("TABLE_CAT");
    schema = rs.getString("TABLE_SCHEM");
    name = rs.getString("TABLE_NAME");
    initColumns(meta);
    }
.......
}
  

Как написать тестовый пример для этого класса, поскольку у обоих из них нет конструктора без параметров.
Насколько я понимаю :

  1. Либо я должен написать конструктор без параметров, либо
  2. Тест с использованием отражения.

Я не могу понять, что мне следует использовать из двух приведенных выше подходов.

  • Какой из них лучше архитектурно и в соответствии с концепцией oops?

  • Есть ли какая-либо другая возможность, кроме указанных выше двух?

  • Есть ли какая-либо ссылка или ресурс для написания тестовых примеров путем рефакторинга кодов такого типа?

Комментарии:

1. Вы не пишете конструктор по умолчанию. Вы пишете конструктор без параметров или позволяете компилятору предоставить вам конструктор по умолчанию.

2. Спасибо за исправление

3. В этом случае вы не можете использовать конструктор по умолчанию, потому что вы уже создали конструкторы для классов. Вы могли бы создать конструкторы без параметров, подобные упомянутым Sotirios, для тестирования ваших классов

4. Я не понимаю, в чем проблема. Вы вызываете конструктор с аргументами, которые хотите использовать в своем тесте, и теперь вызываете метод, который хотите протестировать. Зачем вам нужен конструктор без аргументов?

5. в противном случае я должен передать экземпляр источника данных классу … я действительно не знаю, как писать тестовые примеры. Итак, я немного застрял здесь. Я не знаю, какой подход лучше. Это будет g8, если вы сможете меня направить.

Ответ №1:

Я не уверен, почему вы считаете, что для тестирования необходим конструктор без параметров. Это не так.

параметры в ваших конструкторах являются зависимостями, и ваши модульные тесты должны имитировать эти зависимости, чтобы вы могли протестировать все возможные варианты, которые могут иметь эти зависимости, которые могут повлиять на ваш тестируемый класс.

Например, TableData принимает ResultSet . У вас должен быть тест, который проверяет, правильно ли TableData работает ваш объект, если он создан с пустым результирующим набором (без строк).

Для Java существует несколько библиотек макетов объектов, 2 самых популярных — EasyMock и Mockito.

Синтаксис для этих библиотек немного отличается, но в псевдокоде вот как вы бы тестировали с пустым результирующим набором.

 //NOTE: Pseduocode, will not compile just meant to give you an idea how it works
@Test
public void emptyResultSet(){

     DataBaseMetaData metadata = ...
     ResultSet emptyResultSet = createMock(ResultSet.class);

     //tell the mock to return false when it's next() method is called.
     //this means there are no rows
     when(emptyResultSet.next()).return(false);

     //cut = Class Under Test
     TableData cut = new TableData(emptyResultSet, metadata);
     //assertions go here
  

Комментарии:

1. Похоже, это отвечает на конкретный вопрос, касающийся кода OP. Но предположим TableData , что вам нужно было создать зависимость, чтобы использовать ее с другим C.U.T.? Я рискну предположить, что это то, о чем мог спрашивать OP … (и почему я оказался здесь …)