/
khomec
/
homework6
Обзор
Документация
Войти
/
khomec
/
homework6
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/test/java/sbp/io/JdbcExampleTest.java
433 строки
18 KB
Your Name
h2 db commit +test +javadoc
08 янв 2026, 15:35
08 янв 2026, 15:35
1230383
Код
Авторство
О чём код?
package sbp.io; import org.junit.jupiter.api.*; import org.junit.jupiter.api.io.TempDir; import java.sql.*; import java.nio.file.Path; import java.time.LocalDate; import java.util.List; import static org.junit.jupiter.api.Assertions.*; /** * Тесты для класса JdbcExample. * Проверяют работу с H2 in-memory базой данных и CRUD операции. */ class JdbcExampleTest { private Connection connection; private UsersJdbcRepository repository; @BeforeEach void setUp() throws Exception { // Используем уникальное имя базы для каждого теста String url = "jdbc:h2:mem:testdb_" + System.currentTimeMillis() + ";DB_CLOSE_DELAY=-1;MODE=PostgreSQL"; connection = DriverManager.getConnection(url, "sa", ""); // Создаем таблицу createUsersTable(connection); repository = new UsersJdbcRepository(connection); } @AfterEach void tearDown() throws Exception { if (connection != null && !connection.isClosed()) { connection.close(); } } /** * Копия метода createUsersTable из JdbcExample для использования в тестах. */ private void createUsersTable(Connection conn) throws SQLException { String createTableSQL = "CREATE TABLE IF NOT EXISTS users (" + " login VARCHAR(50) PRIMARY KEY," + " first_name VARCHAR(100) NOT NULL," + " last_name VARCHAR(100) NOT NULL," + " birth_date DATE," + " gender VARCHAR(10)" + ")"; try (Statement stmt = conn.createStatement()) { stmt.execute(createTableSQL); } } @Test @DisplayName("Полный цикл CRUD операций - аналогично JdbcExample.main()") void testFullCrudCycle() { // === Создание пользователя === Users user = new Users("john_doe", "John", "Doe", LocalDate.of(1990, 5, 15), "MALE"); boolean created = repository.createUser(user); assertTrue(created, "Пользователь должен быть создан"); // === Получение пользователя === Users found = repository.getUserByLogin("john_doe"); assertNotNull(found, "Пользователь должен быть найден"); assertEquals("John", found.getFirstName()); assertEquals("Doe", found.getLastName()); assertEquals(LocalDate.of(1990, 5, 15), found.getBirthDate()); assertEquals("MALE", found.getGender()); // === Обновление пользователя === user.setFirstName("Johnny"); boolean updated = repository.updateUser(user); assertTrue(updated, "Пользователь должен быть обновлен"); Users updatedUser = repository.getUserByLogin("john_doe"); assertEquals("Johnny", updatedUser.getFirstName()); // === Удаление пользователя === boolean deleted = repository.deleteUser("john_doe"); assertTrue(deleted, "Пользователь должен быть удален"); Users deletedUser = repository.getUserByLogin("john_doe"); assertNull(deletedUser, "Удаленный пользователь не должен быть найден"); } @Test @DisplayName("Создание нескольких пользователей") void testCreateMultipleUsers() { // Создаем трех пользователей repository.createUser(new Users("user1", "Alice", "Johnson", LocalDate.of(1985, 3, 10), "FEMALE")); repository.createUser(new Users("user2", "Bob", "Williams", LocalDate.of(1990, 7, 20), "MALE")); repository.createUser(new Users("user3", "Charlie", "Brown", LocalDate.of(1995, 11, 30), "MALE")); // Проверяем что все создались assertNotNull(repository.getUserByLogin("user1")); assertNotNull(repository.getUserByLogin("user2")); assertNotNull(repository.getUserByLogin("user3")); // Получаем всех пользователей List<Users> allUsers = repository.getAllUsers(); assertEquals(3, allUsers.size()); } @Test @DisplayName("Попытка создать пользователя с уже существующим логином") void testCreateDuplicateUser() { Users user1 = new Users("same_login", "John", "Doe", LocalDate.of(1990, 1, 1), "MALE"); Users user2 = new Users("same_login", "Jane", "Smith", LocalDate.of(1995, 5, 15), "FEMALE"); // Первый пользователь создается успешно assertTrue(repository.createUser(user1)); // Второй пользователь с тем же логином должен вызвать исключение assertThrows(RuntimeException.class, () -> repository.createUser(user2)); } @Test @DisplayName("Обновление несуществующего пользователя") void testUpdateNonExistentUser() { Users user = new Users("non_existent", "John", "Doe", LocalDate.of(1990, 1, 1), "MALE"); // Обновление несуществующего пользователя должно вернуть false boolean result = repository.updateUser(user); assertFalse(result, "Обновление несуществующего пользователя должно вернуть false"); } @Test @DisplayName("Удаление несуществующего пользователя") void testDeleteNonExistentUser() { // Удаление несуществующего пользователя должно вернуть false boolean result = repository.deleteUser("non_existent"); assertFalse(result, "Удаление несуществующего пользователя должно вернуть false"); } @Test @DisplayName("Поиск несуществующего пользователя") void testGetNonExistentUser() { Users user = repository.getUserByLogin("non_existent"); assertNull(user, "Поиск несуществующего пользователя должен вернуть null"); } @Test @DisplayName("Проверка целостности данных при обновлении") void testDataIntegrityOnUpdate() { // Создаем пользователя Users user = new Users("test_user", "Original", "Name", LocalDate.of(2000, 1, 1), "OTHER"); repository.createUser(user); // Обновляем только имя user.setFirstName("Updated"); repository.updateUser(user); // Проверяем что остальные поля не изменились Users updated = repository.getUserByLogin("test_user"); assertEquals("Updated", updated.getFirstName()); assertEquals("Name", updated.getLastName()); // Должно остаться прежним assertEquals(LocalDate.of(2000, 1, 1), updated.getBirthDate()); assertEquals("OTHER", updated.getGender()); } @Test @DisplayName("Проверка корректности маппинга даты") void testDateMapping() { LocalDate testDate = LocalDate.of(1985, 12, 31); Users user = new Users("date_test", "Test", "User", testDate, "FEMALE"); repository.createUser(user); Users retrieved = repository.getUserByLogin("date_test"); assertEquals(testDate, retrieved.getBirthDate()); } @Test @DisplayName("Проверка работы с пустой базой") void testEmptyDatabase() { List<Users> allUsers = repository.getAllUsers(); assertTrue(allUsers.isEmpty(), "Новая база должна быть пустой"); } @Test @DisplayName("Тест транзакционности - откат при ошибке") void testTransactionRollback() throws SQLException { // Отключаем auto-commit для тестирования транзакций connection.setAutoCommit(false); try { // Создаем первого пользователя repository.createUser(new Users("user1", "Alice", "A", LocalDate.of(1990, 1, 1), "FEMALE")); // Имитируем ошибку - создаем пользователя с пустым именем // (предполагаем что first_name NOT NULL) try { repository.createUser(new Users("user2", null, "B", LocalDate.of(1990, 1, 1), "MALE")); // Если мы здесь, значит база не проверяет NOT NULL (зависит от настроек) } catch (Exception e) { // Ожидаемое исключение } // Откатываем транзакцию connection.rollback(); // Проверяем что изменения не сохранились Users user1 = repository.getUserByLogin("user1"); assertNull(user1, "Пользователь не должен существовать после rollback"); } finally { connection.setAutoCommit(true); } } } /** * Расширенные тесты для проверки различных сценариев использования. */ class JdbcExampleAdvancedTest { @Test @DisplayName("Тестирование с различными типами полей") void testVariousFieldTypes() { // Можно добавить тесты для граничных значений String longLogin = "a".repeat(50); // Максимальная длина String longFirstName = "b".repeat(100); // Создаем пользователя с максимально допустимыми длинами Users user = new Users(longLogin, longFirstName, "Test", LocalDate.now(), "OTHER"); // В реальном тесте нужно создать connection и repository // и проверить что сохранение работает } @Test @DisplayName("Тестирование производительности - создание 1000 пользователей") @Timeout(5) // Тест должен завершиться за 5 секунд void testPerformance() throws Exception { // Подготовка String url = "jdbc:h2:mem:perf_test;DB_CLOSE_DELAY=-1"; try (Connection conn = DriverManager.getConnection(url, "sa", ""); Statement stmt = conn.createStatement()) { stmt.execute("CREATE TABLE users (" + "login VARCHAR(50) PRIMARY KEY," + "first_name VARCHAR(100)," + "last_name VARCHAR(100)," + "birth_date DATE," + "gender VARCHAR(10))"); UsersJdbcRepository repo = new UsersJdbcRepository(conn); // Тест создания 1000 пользователей long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000; i++) { Users user = new Users("user" + i, "Name" + i, "LastName" + i, LocalDate.of(1990 + i % 30, 1 + i % 12, 1 + i % 28), i % 2 == 0 ? "MALE" : "FEMALE"); repo.createUser(user); } long endTime = System.currentTimeMillis(); long duration = endTime - startTime; System.out.println("Создание 1000 пользователей заняло: " + duration + "ms"); assertTrue(duration < 3000, "Создание 1000 пользователей должно занимать менее 3 секунд"); } } } /** * Интеграционные тесты, имитирующие работу JdbcExample.main() */ class JdbcExampleIntegrationTest { @Test @DisplayName("Имитация работы метода main() из JdbcExample") void testJdbcExampleMainFlow() { // Этот тест имитирует точную последовательность из JdbcExample.main() String url = "jdbc:h2:mem:integration_test;DB_CLOSE_DELAY=-1;MODE=PostgreSQL"; try (Connection conn = DriverManager.getConnection(url, "sa", "")) { // Создаем таблицу (как в JdbcExample) String createTableSQL = "CREATE TABLE IF NOT EXISTS users (" + " login VARCHAR(50) PRIMARY KEY," + " first_name VARCHAR(100) NOT NULL," + " last_name VARCHAR(100) NOT NULL," + " birth_date DATE," + " gender VARCHAR(10)" + ")"; try (Statement stmt = conn.createStatement()) { stmt.execute(createTableSQL); } UsersJdbcRepository repository = new UsersJdbcRepository(conn); // 1. Создание пользователя Users user = new Users("john_doe", "John", "Doe", LocalDate.of(1990, 5, 15), "MALE"); repository.createUser(user); // 2. Получение пользователя Users found = repository.getUserByLogin("john_doe"); assertNotNull(found); assertEquals("John", found.getFirstName()); // 3. Обновление пользователя user.setFirstName("Johnny"); repository.updateUser(user); // 4. Проверка обновления Users updated = repository.getUserByLogin("john_doe"); assertEquals("Johnny", updated.getFirstName()); // 5. Удаление пользователя repository.deleteUser("john_doe"); // 6. Проверка удаления Users deleted = repository.getUserByLogin("john_doe"); assertNull(deleted); } catch (Exception e) { fail("Не должно быть исключений: " + e.getMessage()); } } @Test @DisplayName("Тестирование с различными URL H2") void testDifferentH2Urls() throws SQLException { // Тестируем различные варианты URL подключения к H2 // 1. База в памяти (удаляется при закрытии соединения) try (Connection conn1 = DriverManager.getConnection( "jdbc:h2:mem:test1", "sa", "")) { assertFalse(conn1.isClosed()); } // 2. База в памяти с сохранением try (Connection conn2 = DriverManager.getConnection( "jdbc:h2:mem:test2;DB_CLOSE_DELAY=-1", "sa", "")) { assertFalse(conn2.isClosed()); } // 3. Файловая база (для тестирования сохранения на диск) try (Connection conn3 = DriverManager.getConnection( "jdbc:h2:file:./testdb", "sa", "")) { assertFalse(conn3.isClosed()); } } @TempDir Path tempDir; @Test @DisplayName("Тестирование с файловой базой H2") void testFileBasedH2(@TempDir Path tempDir) throws SQLException { // Создаем файловую базу во временной директории String dbPath = tempDir.resolve("testdb").toString(); String url = "jdbc:h2:file:" + dbPath + ";DB_CLOSE_DELAY=-1"; try (Connection conn = DriverManager.getConnection(url, "sa", "")) { // Создаем таблицу try (Statement stmt = conn.createStatement()) { stmt.execute("CREATE TABLE users (" + "login VARCHAR(50) PRIMARY KEY," + "first_name VARCHAR(100))"); stmt.execute("INSERT INTO users VALUES ('test', 'User')"); } // Проверяем что данные сохранились try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM users")) { assertTrue(rs.next()); assertEquals("test", rs.getString("login")); } } // Подключаемся снова - данные должны сохраниться try (Connection conn = DriverManager.getConnection(url, "sa", "")) { try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM users")) { assertTrue(rs.next()); assertEquals("test", rs.getString("login")); } } } } /** * Тесты для проверки обработки ошибок. */ class JdbcExampleErrorHandlingTest { @Test @DisplayName("Тест с некорректными данными") void testInvalidData() throws SQLException { String url = "jdbc:h2:mem:invalid_data_test;DB_CLOSE_DELAY=-1"; try (Connection conn = DriverManager.getConnection(url, "sa", "")) { // Создаем таблицу с NOT NULL ограничениями try (Statement stmt = conn.createStatement()) { stmt.execute("CREATE TABLE users (" + "login VARCHAR(50) PRIMARY KEY NOT NULL," + "first_name VARCHAR(100) NOT NULL)"); } UsersJdbcRepository repo = new UsersJdbcRepository(conn); // Попытка создать пользователя с null логином Users invalidUser = new Users(null, "Name", "LastName", LocalDate.now(), "MALE"); // Должно выбросить исключение при попытке вставить null в NOT NULL поле assertThrows(Exception.class, () -> repo.createUser(invalidUser)); } } }