#java #unit-testing #junit #bytearray #junit4
#java #модульное тестирование #junit #bytearray #junit4
Вопрос:
Я реализовал очень простой класс с именем Enigma
, который имеет симметричный ключ и два метода: byte[] encryptString(String strToEncrypt)
и String decryptBytes(byte[] arrayToDecrypt)
.
Я пытаюсь написать несколько тестов для этих методов. Я думал о том, чтобы проверить, что методы шифрования и дешифрования являются обратными друг другу, но это ничего не говорит о каждом из них в отдельности. Я хотел использовать методы в том виде, в каком они есть сейчас, чтобы получить набор входных / выходных данных и установить их в качестве тестов (я знаю, что это не идеально, но цель этих тестов — гарантировать, что функция будет вести себя в будущем так же, как и сегодня, а не то, что шифрование / дешифрованиехорошо).
Однако я не знаю, как получить представление вывода массива байтов byte[] encryptString(String strToEncrypt)
, чтобы я мог жестко закодировать его в тестовом классе.
Есть идеи?
Ответ №1:
Несколько замечаний о том, как это проверить (предупреждение о личном мнении :-))
- Если вы пишете модульные тесты, избегайте чтения ожидаемых результатов из файлов, поскольку это замедляет тест (модульные тесты должны быть очень быстрыми), а также создает другую вещь, не имеющую отношения к вашему коду, которая может пойти не так (т. Е. Файл может быть удален и т.д.)
- Не используйте тот же метод, который вы тестируете, для получения ожидаемых результатов, с помощью которых вы проверяете метод. Это бессмысленно, если вы пытаетесь проверить алгоритм, и может увековечить ошибки в алгоритме
- Учтите тот факт, что наименьшая единица работы в Java — это класс, а не метод (забудьте на секунду о лямбда-выражениях Java 8, вы не будете писать модульные тесты для них напрямую), поэтому вам следует попытаться протестировать класс, а не методы
Мой последний пункт подводит меня (наконец?) к рекомендации. Подумайте о том, за что отвечает класс (надеюсь, единственная ответственность, см. SRP). В этом случае я считаю, что ответственность вашего класса заключается в двустороннем шифровании строк.
Поэтому я бы написал следующие тесты:
@Test
public void testThatEncryptingStringResultsInExpectedBytes() {
byte[] encryption = enigma.encryptString(TEST_STRING);
assertArrayEquals(EXPECTED_ENCRYPTION, encryption);
}
@Test
public void testThatDecryptinEncryptionResultsInOriginalString() {
String decryption = enigma.decryptBytes(TEST_ENCRYPTION);
assertEquals(EXPECTED_ORIGINAL_STRING, decryption);
}
@Test
public void testThatDecriptionReversesEncryption() {
String decryption = enigma.decryptBytes(enigma.encryptString(TEST_STRING));
assertEquals(TEST_STRING, decryption);
}
@Test
public void testThatEncryptionReversesDecryption() {
byte[] encryption = enigma.encriptString(enigma.decryptBytes(TEST_ENCRYPTION));
assertEquals(TEST_ENCRYPTION, encryption);
}
Возможно, добавьте еще несколько тестов, чтобы проверить, что попытка зашифровать / расшифровать недопустимые значения вызывает исключения и другие случаи ошибок.
Комментарии:
1. Спасибо, это то, что я, наконец, сделал (используя онлайн-инструмент шифрования для получения результатов в шестнадцатеричном формате).
2. комментарий и вопрос: не уверен, что обратные тесты могут быть применены к каждому шифрованию (думаю, это имеет смысл только для симметричных алгоритмов). Я согласен, что чтение файлов замедляет модульные тесты, которые должны быть молниеносными.. Как бы вы обошли это при тестировании генерации xml с помощью JUnit? какие-либо советы или примеры по этому поводу?
3. Прежде всего, позвольте мне просто подчеркнуть, что более серьезной проблемой, чем медлительность (хотя и БОЛЬШАЯ проблема) при чтении файлов во время модульного тестирования, является несогласованность, потеря повторяемости и потеря изоляции. Чтение файлов зависит от ввода-вывода, что означает, что может произойти сбой, каждый запуск может занимать разное время и т. Д. Выполнение операций ввода-вывода во время теста не позволяет ему быть модульным тестом. Что касается генерации XML, определите свой генератор для получения выходного файла записи / потока в качестве параметра конструктора / метода или путем инъекции. Модульный тест предоставит макет выходного буфера.
4. Извините за короткий ответ, количество символов в комментарии ограничено. Если вам нужен лучший ответ, пожалуйста, отправьте вопрос, и я отвечу на него должным образом.
5. Я сталкиваюсь с той же проблемой, но проблема в том, что мой шифровальщик использует случайную соль, поэтому зашифрованное значение невозможно ожидать.