2015-12-15 2 views
0

Я пытаюсь определить лучший способ написать тестовый код. Вот мой кодпишущий тестируемый код в этом сценарии

class FileReader { 

    private FileInputStream input; 

    public FileReader(FileInputStream input) { 
     this.input = input; 
    } 

    public void read() throws IOException { 
     Row row = readHeaderRow(); 
     Row[] rows = readOtherRowsBasedOnHeader(row); 
     doSomethingElse(rows); 
    } 

    private void readHeaderRow() { 
     //.. 
    } 
    private void readOtherRowsBasedOnHeader(Row row) { 
     //.. 
    } 
    private void doSomethingElse(Row[] rows) { 
     //.. 
    } 
} 

Как вы можете видеть выше, только метод read() является общедоступным. Остальные методы являются частными. Должен ли я просто оставлять частные методы из тестирования? Или имеет смысл делать все методы общедоступными и делать то, что делает read() в вызывающем коде?

+2

Вы не должны публиковать или закрывать методы для написания проверяемого кода. Вы всегда можете использовать Reflection для тестирования частных методов вашего класса. – vk239

+0

Тестирование фреймворков, таких как Junit/TestNG, поддерживает такое тестирование на основе отражения из коробки? – Jay

+1

Вот ссылка, в которой есть статья о тестировании частных методов с использованием Junit и reflection - http://www.jroller.com/CoBraLorD/entry/junit_testing_private_fields_and – vk239

ответ

1

Если логика частных методов (readHeaderRow, readOtherRowsBasedOnHeader, ...) является сложной и требуют отдельных тестов, я предлагаю реализовать FileReader как меньшие классы composition. Это было бы примерно так:

class FileReader { 

private FileHeaderReader headerReader = new FileHeaderReader(); 
private FileOtherReader otherReader = new FileOtherReader(); 
//.... 
private FileInputStream input; 

public FileReader(FileInputStream input) { 
    this.input = input; 
} 

public void read() throws IOException { 
    Row row = headerReader.read(); 
    Row[] rows = otherReader.read(row); 
    //do something else 
} 
} 

class FileHeaderReader { 
    public Row read() {...} 
} 
//.... 

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

+0

Я думал об этом, но я подумал, буду ли я продолжать это делать, я бы назвал классный взрыв. – Jay

+0

Это не общее решение. Просто один из многих. Всегда используйте свой ум, чтобы решить, какой путь будет лучшим. Независимо от того, что не бойтесь иметь много классов и помните, что композиция объекта обычно приводит к более тестируемому коду. –

1

Если тестирование общедоступного метода охватывает весь код в частных методах, безопасно рассматривать класс Испытан

+0

ok, очень действительный ответ. – Jay

2

Мое мнение состоит в том, что вы должны тестировать только общедоступные методы. Использование частных методов будет проверяться независимо от вызовов общедоступного метода. Он также сделает внутренний рефакторинг намного проще без изменения теста.

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

1

Я вижу два жизнеспособных варианта.

  1. Вы протестировать чтения(), так что ваш тест должен охватывать условия и состояния изменились в частных методов. Это зависит от ответственности и сложности этих методов, хотите ли вы этого сделать.
  2. Вы узнаете, что эти частные методы нарушают SRP и разделяют их, чтобы они теперь были публичными в другом классе.
Смежные вопросы