1+ package com .opensourcewithslu .inputdevices ;
2+
3+ import com .pi4j .context .Context ;
4+ import com .pi4j .io .spi .Spi ;
5+ import com .pi4j .io .spi .SpiConfig ;
6+ import org .junit .jupiter .api .Test ;
7+ import org .junit .jupiter .api .BeforeEach ;
8+ import org .slf4j .Logger ;
9+ import org .slf4j .LoggerFactory ;
10+ import java .lang .reflect .Field ;
11+
12+ import static org .junit .jupiter .api .Assertions .*;
13+ import static org .mockito .ArgumentMatchers .*;
14+ import static org .mockito .Mockito .*;
15+
16+ public class ThermistorHelperTest {
17+
18+ private static final Logger log = LoggerFactory .getLogger (ThermistorHelperTest .class );
19+
20+
21+ private Context mockContext ;
22+ private Spi mockSpi ;
23+ private ThermistorHelper thermistorHelper ;
24+
25+ @ BeforeEach
26+ void setUp () {
27+ mockContext = mock (Context .class );
28+ mockSpi = mock (Spi .class );
29+
30+ // Mock Pi4J to return our Spi mock
31+ when (mockContext .create (any (SpiConfig .class ))).thenReturn (mockSpi );
32+
33+ thermistorHelper = new ThermistorHelper (mockContext );
34+
35+ }
36+
37+ @ Test
38+ void testInitializeADC_createsSpiConfig () {
39+ // Verify that spi was created with spiconfig
40+ verify (mockContext ).create (any (SpiConfig .class ));
41+ }
42+
43+ @ Test
44+ void testReadADCValue_successfulRead () throws Exception {
45+ ThermistorHelper spyHelper = spy (thermistorHelper );
46+
47+ // Replace spi field with our mock
48+ doReturn (mockSpi ).when (spyHelper ).getSpi ();
49+
50+ // Mock spi.read() to fill buffer with fake ADC response
51+ doAnswer (invocation -> {
52+ byte [] buffer = invocation .getArgument (0 );
53+ buffer [0 ] = 0x00 ; // unused
54+ buffer [1 ] = 0x02 ; // upper 2 bits (binary 10)
55+ buffer [2 ] = (byte ) 0xAB ; // lower 8 bits (171)
56+ return null ;
57+ }).when (mockSpi ).read (any (byte [].class ));
58+ double adcValue = spyHelper .readADCValue ();
59+ log .info ("Test successful ADC read, got value: {}" , adcValue );
60+ assertEquals (683.0 , adcValue , "ADC value should be correctly decoded" );
61+ }
62+ @ Test
63+ void testReadADCValue_failureReturnsMinusOne () throws Exception {
64+ ThermistorHelper spyHelper = spy (thermistorHelper );
65+
66+
67+ doReturn (mockSpi ).when (spyHelper ).getSpi ();
68+
69+
70+ doThrow (new RuntimeException ("SPI failure" )).when (mockSpi ).read (any (byte [].class ));
71+ double adcValue = spyHelper .readADCValue ();
72+ assertEquals (-1.0 , adcValue , "On failure, readADCValue should return -1" );
73+ }
74+
75+
76+ @ Test
77+ void testGetResistanceConversion () {
78+ ThermistorHelper spyHelper = spy (thermistorHelper );
79+
80+ doReturn (512.0 ).when (spyHelper ).readADCValue ();
81+ double resistance = spyHelper .getResistance ();
82+ // Expected formula result
83+ double voltage = (512.0 / 1023.0 ) * 3.3 ;
84+ double expectedResistance = (10000 * (3.3 - voltage )) / voltage ;
85+ assertEquals (expectedResistance , resistance , 0.01 , "Resistance should be calculated correctly" );
86+ }
87+
88+ @ Test
89+ void testGetTemperatureInCelsiusus () {
90+ ThermistorHelper spyHelper = spy (thermistorHelper );
91+ // Mock resistance to predict Celsius
92+ doReturn (10000.0 ).when (spyHelper ).getResistance ();
93+ double expectedCelsius = 1.0 /
94+ (0.001129148 + 0.000234125 * Math .log (10000.0 )
95+ + 0.0000000876741 * Math .pow (Math .log (10000.0 ), 3 ))
96+ - 273.15 ;
97+ double actual = spyHelper .getTemperatureInCelsius ();
98+ assertEquals (expectedCelsius , actual , 0.01 , "Temperature in Celsius should be correct" );
99+ }
100+
101+ @ Test
102+ void testGetTemperatureInFahrenheit () {
103+ ThermistorHelper spyHelper = spy (thermistorHelper );
104+ // Mock Celsius conversion
105+ doReturn (25.0 ).when (spyHelper ).getTemperatureInCelsius ();
106+ // expected answer is 25 * 9/5 + 32 = 77
107+ double fahrenheit = spyHelper .getTemperatureInFahrenheit ();
108+ assertEquals (77.0 , fahrenheit , 0.01 , "Fahrenheit should be Celsius * 9/5 + 32" );
109+ }
110+ }
0 commit comments