2016-07-14 1 views
1

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

Если это будет так: 1-)

@Test 
public void testDelete() throws SQLException { 
    // Given 
    String dateStr = "09-May-2016"; 
    String word = "testWord"; 
    derbyDb.save(dateStr, word, 9); 
    derbyDb.save(dateStr, word, 11); 

    // When 
    assertEquals(2, derbyDb.contain(dateStr, word)); 
    derbyDb.delete(); 

    // then 
    assertEquals(0, derbyDb.contain(dateStr, word)); 
} 

(Вы видите здесь, я использовал 'спасти' метод)

2-)

@Test 
public void testDelete() throws SQLException { 
    // Given 
    String dateStr = "09-May-2016"; 
    String word = "testWord"; 
    PreparedStatement insertemp = conn 
       .prepareStatement("insert into " + tableName + "(PUBLISHDATE,WORD,FREQUENCY) values(?,?,?)"); 
     insertemp.setString(1, dateStr); 
     insertemp.setString(2, word); 
     insertemp.setInt(3, frequency); 
     insertemp.executeUpdate(); 

    // When 
    assertEquals(2, derbyDb.contain(dateStr, word)); 
    derbyDb.delete(); 

    // then 
    assertEquals(0, derbyDb.contain(dateStr, word)); 
} 

Который один. истинно или лучше? Или должен ли модуль тестирования быть независимым от других функций?

EDIT: AssertEquals, добавленные перед удалением.

EDIT-2: Во втором варианте должен быть только один метод, который является «удалением» и будет независим от других методов класса. Поэтому вместо того, чтобы содержать метод, должен быть запрос.

+1

В любом случае вы должны 'assertEquals (2, derbyDb.contain (dateStr, word));' перед удалением, поэтому вы знаете, что 'delete' является причиной, по которой она равна нулю после. –

+0

Первый будет более ясным, если * testDelete * зависит (например, с [TestNG «dependsOn»] (http://testng.org/javadocs/org/testng/annotations/Test.html#dependsOnMethods--)) on методы тестирования для 'save'. – Tom

+0

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

ответ

2

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

В качестве альтернативы вы можете сделать вложение записей для удаления в методе @Before, чтобы вы просто имели delete в фактическом тесте, чтобы было ясно, что это то, что тестируется в методе.

В любом случае, вы должны assertEquals(2, derbyDb.contain(dateStr, word)); перед удалением, так что вы знаете, что delete является причиной того, что он равен нулю после.


Тестирование Google на унитаз блоге есть пост, связанный с этим: "Test Behavior, Not Implementation".

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

Дублирование логики уровня базы данных в тестах - это проверка реализации. Возможно, вам понадобятся следующие изменения:

  • Переименование таблиц и столбцов базы данных;
  • Изменение класса derbyDb для использования какого-либо другого базового хранилища - возможно, вам нужна его реализация в памяти или что-то, с чем вы не можете подключиться к JDBC.

Если вы взяли второй подход, вам нужно пойти и исправить тесты, а также тестируемый код.

Если вы сделали первый подход, вы этого не сделаете. Все «просто работает» в тесте - или это не так, но тогда вы знаете, что это ошибочная реализация, а не ошибочный тест.

1

Последнее безопаснее, поскольку в первом случае вы рискуете выйти из строя первого метода - если derbyDb.save() не работает должным образом, вы можете получить ошибку на тестируемом методе, который был бы ложным.

С другой стороны, если у вас есть отдельный тест для метода .save(), использование первого теста намного яснее. В конце концов, если ваша сборка завершится неудачно на одном или двух тестах, это не имеет большого значения - есть еще код для исправления. Просто убедитесь, что вы проверяете все методы, которые вы используете в других тестах.

Возможно, хорошим подходом было бы использование только тех методов, которые уже были проверены в предыдущих тестах.

Смежные вопросы