From 701cc0a8b658f59a74d4ee685446b6286ed74e58 Mon Sep 17 00:00:00 2001 From: naumueller <> Date: Thu, 12 Feb 2026 22:16:35 +0100 Subject: [PATCH] Adjusted Services and Unit-(Int-like)-Tests --- .gitignore | 1 + data/health.db | Bin 0 -> 12288 bytes pom.xml | 37 ++++++-- .../virtueller_gesundheitsassistent/App.java | 14 ++- .../service/BinaryEventService.java | 40 +++++++++ .../service/DataPersistenceService.java | 38 ++++++-- .../service/EvaluationService.java | 4 - .../service/StatisticsService.java | 20 ++--- .../service/BinaryEventServiceTest.java | 58 +++++++++++++ .../service/DataPersistenceServiceTest.java | 56 ++++++++++++ .../service/EvaluationServiceTest.java | 59 +++++++++++++ .../service/StatisticsServiceTest.java | 82 ++++++++++++++++++ 12 files changed, 381 insertions(+), 28 deletions(-) create mode 100644 .gitignore create mode 100644 data/health.db create mode 100644 src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/BinaryEventService.java create mode 100644 src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/BinaryEventServiceTest.java create mode 100644 src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/DataPersistenceServiceTest.java create mode 100644 src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/EvaluationServiceTest.java create mode 100644 src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/StatisticsServiceTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b7eda --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/nbproject/ diff --git a/data/health.db b/data/health.db new file mode 100644 index 0000000000000000000000000000000000000000..212f01e9abac2abdc6b184c5f298b1447898a6ed GIT binary patch literal 12288 zcmeI2&rTCT7{GVi3W9dGaOuU6>45|UCNs0M^Jgzwbwe6U!Ll5BBCW1T6Iz89j7Lp8 zdiE830uMfcui(KaF!9dKZz0uEHu0v3`Mz}9oy>2(Kfl`~-G9>Tk5lse#mS&MCV^9N zT-Uizh~qfR@D$;hgbOdF$pU_}^`Bzdq3_SjKoxw~@%P~i0}Y@7G=K)s02)98XaEhM z0W^RH(7?YiuveI?Zfv-nakqDrj*gGuHhefrk5AL#)7fS5VLPrTF-htVnlYJS*M{9e zx(O%O-`sWQtE;Q-+v-KmUVqp^53(cqeWpn-}C+_vkeJ1-Et+(mH51FZag%K{^_D2QSGZ=sjud#AE`% z+4byhzEu9?_}~1`{s;e+pZMJOyzkx@@1yt5>v{LQJLU88S3oe(02)98XaEhM0W^RH z&;S}h18Cr{8>lUnoP}+{gxX?ai;F~vh_fg(R9dBk;Eb(Q0I5$SJVT_UQd%oj&7V!d zBc`Je_En&*4H>I>vj~&`N>QVw(p&;kzK%c^A*p6z)(arFa}ma<33O<<0OZycgeQVU zfr46;D`ge8FwP<%zsI>mf=F7bg)m`ITgXYlvlK=eW3_=QH?JeYW+|j%&_~wDd=6rw zKv1SYr3nC;%R$0S3WG{YXUL5lL_`6MV@=2!zM4FXmxUQfZH5lfX; z%E+urAqUYBGgMp6VP-(w97IJ-Py@3F2@_}cf7k!vzy|{jpaC?12G9T+Km%w14WI!u VfCkV28u%{^RNUgKJN;LKrJo>r)P?{6 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 7524240..9d55e46 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 efi.projekt Virtueller_Gesundheitsassistent @@ -48,6 +48,31 @@ sqlite-jdbc 3.51.1.0 + + org.junit.jupiter + junit-jupiter-api + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-params + 5.6.0 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.0 + test + + + org.mockito + mockito-core + 5.11.0 + test + jar + @@ -96,11 +121,11 @@ ide-profile - - - - - + + + + + diff --git a/src/main/java/efi/projekt/virtueller_gesundheitsassistent/App.java b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/App.java index 1977a02..43d9576 100644 --- a/src/main/java/efi/projekt/virtueller_gesundheitsassistent/App.java +++ b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/App.java @@ -1,6 +1,7 @@ package efi.projekt.virtueller_gesundheitsassistent; import efi.projekt.virtueller_gesundheitsassistent.model.AppState; +import efi.projekt.virtueller_gesundheitsassistent.service.BinaryEventService; import efi.projekt.virtueller_gesundheitsassistent.service.DataPersistenceService; import efi.projekt.virtueller_gesundheitsassistent.service.EvaluationService; import efi.projekt.virtueller_gesundheitsassistent.service.MqttClientService; @@ -29,6 +30,7 @@ public class App extends Application { private EvaluationService evaluationService; private UnrealWebSocketService unrealService; private MqttClientService mqttService; + private BinaryEventService binaryEventService; @Override public void start(Stage primaryStage) throws IOException { @@ -38,7 +40,7 @@ public class App extends Application { // ========================= // Unreal-WebService - unrealService = new UnrealWebSocketService("127.0.0.1"); + unrealService = new UnrealWebSocketService("ws://localhost:8080/avatar"); // MQTT-Service mqttService = new MqttClientService(); @@ -47,13 +49,21 @@ public class App extends Application { persistenceService = new DataPersistenceService(); // Statistik-Service - statisticsService = new StatisticsService(); + statisticsService = new StatisticsService(persistenceService); // Evaluationsservice evaluationService = new EvaluationService(statisticsService, appState, unrealService); + binaryEventService = new BinaryEventService(persistenceService, evaluationService); + // ========================= + // MQTT Subscribe + // ========================= + mqttService.subscribe("STATE", payload -> + binaryEventService.handlePayload(payload) + ); + // ========================= // UI laden // ========================= diff --git a/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/BinaryEventService.java b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/BinaryEventService.java new file mode 100644 index 0000000..fe63eb4 --- /dev/null +++ b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/BinaryEventService.java @@ -0,0 +1,40 @@ +package efi.projekt.virtueller_gesundheitsassistent.service; + +import efi.projekt.virtueller_gesundheitsassistent.util.Logger; + +/** + * + * @author naumueller + */ +public class BinaryEventService { + + private final DataPersistenceService persistenceService; + private final EvaluationService evaluationService; + + public BinaryEventService( + DataPersistenceService persistenceService, + EvaluationService evaluationService + ) { + this.persistenceService = persistenceService; + this.evaluationService = evaluationService; + } + + public void handlePayload(String payload) { + try { + int value = Integer.parseInt(payload); + + if (value != 0 && value != 1) { + Logger.warn("EVENT", "Ungültiger Wert: " + payload); + return; + } + + persistenceService.store(value); + + evaluationService.evaluate(); + + + } catch (NumberFormatException e) { + Logger.warn("EVENT", "Payload nicht numerisch " + payload); + } + } +} diff --git a/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/DataPersistenceService.java b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/DataPersistenceService.java index 955d329..4c8af64 100644 --- a/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/DataPersistenceService.java +++ b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/DataPersistenceService.java @@ -1,10 +1,7 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package efi.projekt.virtueller_gesundheitsassistent.service; import efi.projekt.virtueller_gesundheitsassistent.util.Logger; +import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -18,12 +15,34 @@ import java.time.LocalDateTime; */ public class DataPersistenceService { - private static final String DB_URL = "jdbc:sqlite:data/health.db"; + private static final String DB_FOLDER = "data"; + private final String DB_URL; public DataPersistenceService() { + this("jdbc:sqlite:data/health.db"); + createDatabaseFolder(); init(); } + // Für Tests + public DataPersistenceService(String DB_URL) { + this.DB_URL = DB_URL; + createDatabaseFolder(); + init(); + } + + public void createDatabaseFolder() { + File folder = new File(DB_FOLDER); + if (!folder.exists()) { + boolean created = folder.mkdirs(); + if (created) { + Logger.info("DB", "Datenbank-Ordner erstellt"); + } else { + Logger.warn("DB", "Konnte DB-Ordner nicht erstellen"); + } + } + } + private void init() { try ( Connection c = DriverManager.getConnection(DB_URL); Statement s = c.createStatement()) { @@ -44,7 +63,10 @@ public class DataPersistenceService { } public void store(int value) { - try (Connection c = DriverManager.getConnection(DB_URL); PreparedStatement ps = c.prepareStatement("INSERT INTO binary_event (value, timestamp) VALUES (?, ?)")) { + try ( + Connection c = DriverManager.getConnection(DB_URL); PreparedStatement ps = c.prepareStatement( + "INSERT INTO binary_event (value, timestamp) VALUES (?, ?)" + )) { ps.setInt(1, value); ps.setString(2, LocalDateTime.now().toString()); ps.executeUpdate(); @@ -52,4 +74,8 @@ public class DataPersistenceService { Logger.error("DB", "Database Insert fehlgeschlagen", e); } } + + public String getDbUrl() { + return DB_URL; + } } diff --git a/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/EvaluationService.java b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/EvaluationService.java index 1e67062..3fe827e 100644 --- a/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/EvaluationService.java +++ b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/EvaluationService.java @@ -1,7 +1,3 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package efi.projekt.virtueller_gesundheitsassistent.service; import efi.projekt.virtueller_gesundheitsassistent.model.AppState; diff --git a/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/StatisticsService.java b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/StatisticsService.java index a0bdc8b..9c4986b 100644 --- a/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/StatisticsService.java +++ b/src/main/java/efi/projekt/virtueller_gesundheitsassistent/service/StatisticsService.java @@ -1,7 +1,3 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package efi.projekt.virtueller_gesundheitsassistent.service; import efi.projekt.virtueller_gesundheitsassistent.util.Logger; @@ -17,7 +13,11 @@ import java.sql.SQLException; */ public class StatisticsService { - private static final String DB_URL = "jdbc:sqlite:data/health.db"; + private final DataPersistenceService persistenceService; + + public StatisticsService(DataPersistenceService persistenceService) { + this.persistenceService = persistenceService; + } public double getRatio(int lastN) { String query = """ @@ -25,14 +25,14 @@ public class StatisticsService { FROM ( SELECT value FROM binary_event - ORDER BY timestamp DESC + ORDER BY id DESC LIMIT ? ) """; - - try (Connection c = DriverManager.getConnection(DB_URL); PreparedStatement ps = c.prepareStatement(query)) { + + try (Connection c = DriverManager.getConnection(persistenceService.getDbUrl()); PreparedStatement ps = c.prepareStatement(query)) { ps.setInt(1, lastN); - + ResultSet rs = ps.executeQuery(); if (rs.next()) { return rs.getDouble(1); @@ -40,7 +40,7 @@ public class StatisticsService { } catch (SQLException e) { Logger.error("Evaluation", "Couldn't get ratio.", e); } - + return 0.0; } } diff --git a/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/BinaryEventServiceTest.java b/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/BinaryEventServiceTest.java new file mode 100644 index 0000000..2ee8a7b --- /dev/null +++ b/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/BinaryEventServiceTest.java @@ -0,0 +1,58 @@ +package efi.projekt.virtueller_gesundheitsassistent.service; + +import org.junit.jupiter.api.*; +import static org.mockito.Mockito.*; + +/** + * + * @author naumueller + */ +class BinaryEventServiceTest { + + private DataPersistenceService persistenceService; + private EvaluationService evaluationService; + private BinaryEventService binaryEventService; + + @BeforeAll + public static void setUpClass() { + } + + @AfterAll + public static void tearDownClass() { + } + + @BeforeEach + public void setUp() { + persistenceService = mock(DataPersistenceService.class); + evaluationService = mock(EvaluationService.class); + binaryEventService = new BinaryEventService(persistenceService, evaluationService); + } + + @AfterEach + public void tearDown() { + persistenceService = null; + evaluationService = null; + binaryEventService = null; + } + + @Test + void testHandlePayloadValid() { + binaryEventService.handlePayload("1"); + verify(persistenceService).store(1); + verify(evaluationService).evaluate(); + } + + @Test + void testHandlePayloadInvalidValue() { + binaryEventService.handlePayload("5"); + verify(persistenceService, never()).store(anyInt()); + verify(evaluationService, never()).evaluate(); + } + + @Test + void testHandlePayloadNonNumeric() { + binaryEventService.handlePayload("abc"); + verify(persistenceService, never()).store(anyInt()); + verify(evaluationService, never()).evaluate(); + } +} diff --git a/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/DataPersistenceServiceTest.java b/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/DataPersistenceServiceTest.java new file mode 100644 index 0000000..1ac57c0 --- /dev/null +++ b/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/DataPersistenceServiceTest.java @@ -0,0 +1,56 @@ +package efi.projekt.virtueller_gesundheitsassistent.service; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.*; + +/** + * + * @author naumueller + */ +public class DataPersistenceServiceTest { + + private DataPersistenceService persistenceService; + private static final String IN_MEMORY_DB = "jdbc:sqlite:data/health.db"; + + public DataPersistenceServiceTest() { + } + + @BeforeAll + public static void setUpClass() { + } + + @AfterAll + public static void tearDownClass() { + } + + @BeforeEach + public void setUp() { + persistenceService = new DataPersistenceService(IN_MEMORY_DB); + } + + @AfterEach + public void tearDown() { + persistenceService = null; + } + + @Test + void testStoreAndRetrieveValue() throws SQLException { + persistenceService.store(1); + + try (Connection c = DriverManager.getConnection(IN_MEMORY_DB); + PreparedStatement ps = c.prepareStatement("SELECT value FROM binary_event")) { + ResultSet rs = ps.executeQuery(); + Assertions.assertTrue(rs.next()); + Assertions.assertEquals(1, rs.getInt("value")); + } + } + +} diff --git a/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/EvaluationServiceTest.java b/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/EvaluationServiceTest.java new file mode 100644 index 0000000..0d222a5 --- /dev/null +++ b/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/EvaluationServiceTest.java @@ -0,0 +1,59 @@ +package efi.projekt.virtueller_gesundheitsassistent.service; + +import efi.projekt.virtueller_gesundheitsassistent.model.AppState; +import efi.projekt.virtueller_gesundheitsassistent.model.ProblemLevel; +import org.junit.jupiter.api.*; + +import static org.mockito.Mockito.*; + +/** + * + * @author naumueller + */ +class EvaluationServiceTest { + + private StatisticsService statisticsService; + private AppState appState; + private UnrealWebSocketService unrealService; + private EvaluationService evaluationService; + + @BeforeAll + public static void setUpClass() { + } + + @AfterAll + public static void tearDownClass() { + } + + @BeforeEach + public void setUp() { + statisticsService = mock(StatisticsService.class); + appState = new AppState(); + unrealService = mock(UnrealWebSocketService.class); + evaluationService = new EvaluationService(statisticsService, appState, unrealService); + } + + @AfterEach + public void tearDown() { + statisticsService = null; + appState = null; + unrealService = null; + evaluationService = null; + } + + @Test + void testEvaluateDisasterLevel() { + when(statisticsService.getRatio(anyInt())).thenReturn(0.95); + evaluationService.evaluate(); + Assertions.assertEquals(ProblemLevel.DISASTER, appState.getProblemLevel()); + verify(unrealService).speak("DISASTER"); + } + + @Test + void testEvaluateNoChange() { + appState.setProblemLevel(ProblemLevel.NONE); + when(statisticsService.getRatio(anyInt())).thenReturn(0.1); + evaluationService.evaluate(); + verify(unrealService, never()).speak(anyString()); + } +} diff --git a/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/StatisticsServiceTest.java b/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/StatisticsServiceTest.java new file mode 100644 index 0000000..ecce3b8 --- /dev/null +++ b/src/test/java/efi/projekt/virtueller_gesundheitsassistent/service/StatisticsServiceTest.java @@ -0,0 +1,82 @@ +package efi.projekt.virtueller_gesundheitsassistent.service; + +import java.io.File; +import org.junit.jupiter.api.*; +import java.sql.*; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * + * @author naumueller + */ +class StatisticsServiceTest { + + private String DB_URL; + private DataPersistenceService persistenceService; + private StatisticsService statisticsService; + private File tempDbFile; + + @BeforeAll + public static void setUpClass() { + } + + @AfterAll + public static void tearDownClass() { + } + + @BeforeEach + public void setUp() throws SQLException { + try { + tempDbFile = File.createTempFile("testdb", ".db"); + } catch (Exception e) { + throw new RuntimeException("Kann temporäre DB-Datei nicht erstellen", e); + } + DB_URL = "jdbc:sqlite:" + tempDbFile.getAbsolutePath(); + persistenceService = new DataPersistenceService(DB_URL); + statisticsService = new StatisticsService(persistenceService); + } + + @AfterEach + public void tearDown() { + if (tempDbFile != null && tempDbFile.exists()) { + tempDbFile.delete(); + } + } + + @Test + void testGetRatioNoData() { + double ratio = statisticsService.getRatio(10); + assertEquals(0.0, ratio, "Ratio sollte 0 sein, wenn keine Daten vorhanden"); + } + + @Test + void testGetRatioSingleValue() throws SQLException { + persistenceService.store(1); + + double ratio = statisticsService.getRatio(1); + assertEquals(1.0, ratio, "Ratio sollte 1 sein, wenn nur 1 gespeichert wurde"); + } + + @Test + void testGetRatioMultipleValues() throws SQLException { + persistenceService.store(1); + persistenceService.store(0); + persistenceService.store(1); + + double ratio = statisticsService.getRatio(10); + assertEquals((1 + 0 + 1) / 3.0, ratio, 0.0001, "Ratio sollte Durchschnitt der letzten Werte sein"); + } + + @Test + void testGetRatioLimitLastN() throws SQLException { + persistenceService.store(1); + persistenceService.store(1); + persistenceService.store(0); + persistenceService.store(0); + persistenceService.store(1); + + double ratio = statisticsService.getRatio(3); + assertEquals((1 + 0 + 0) / 3.0, ratio, 0.0001, "Ratio sollte nur die letzten N Werte berücksichtigen"); + } +} \ No newline at end of file