Mockowanie zmiennych wewnątrz metody testowanej.

Mockowanie zmiennych wewnątrz metody testowanej.
I9
  • Rejestracja:około 14 lat
  • Ostatnio:około miesiąc
  • Postów:55
0

Cześć, jak przetestować poniższy kod?

Kopiuj
@Service
public class Premia {
    public double oblicz(double baza) {
        double retn = 0d;
        ZonedDateTime zdt = ZonedDateTime.now();
        if (zdt.getMonth() == Month.FEBRUARY) {
            retn = 3d;
        } else {
            retn = 1.1d;
        }
        return retn * baza;
    }
}

Założenia: Nie można modyfikować kodu oraz pomijamy, że został użyty typ double.

Próbowałem z PowerMock oraz szukałem rozwiązań, ale nic mogę nic znaleźć :(

Test, który próbowałem skleić ....

Kopiuj
@SpringBootTest()
@PrepareForTest({ZonedDateTime.class})
class Demo2ApplicationTests {

	@Autowired
	Premia premia;
	@Test
	void mocking() throws Exception {
		PowerMockito.mockStatic(ZonedDateTime.class);
		ZonedDateTime zdt  = ZonedDateTime.of(2020,2,2,2,2,2,2,ZoneId.of("+1"));
		PowerMockito.when(ZonedDateTime.now()).thenReturn(zdt);
		Assertions.assertThat(premia.oblicz(1200)).isEqualTo(3600);
	}

}

W jaki sposób mokujecie wewnętrzne zmienne?
Z góry dzięki za pomoc


lato-zima.pl
while(question != true) {
ask();
}
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
2

Mockowanie statickow to sredni pomysl.
Jakis czas temu grozilo to wyciekami pamieci.
Widziales to?
https://www.codeproject.com/Articles/806508/Using-PowerMockito-to-Mock-Final-and-Static-Method

I9
  • Rejestracja:około 14 lat
  • Ostatnio:około miesiąc
  • Postów:55
1

@vpiotr: Dziękuję za artykuł zaraz się z nim zapoznam.

Dostałem podobne zadanie na jednej z rozmów rekrutacyjnych. Klasę Premia mam traktrować jako legacy code i muszę przetestować ten przypadek.


lato-zima.pl
while(question != true) {
ask();
}
99xmarcin
Uważaj bo to może być rozgrzewka przed robotą, a akurat ten kod można łatwo naprawić...
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 9 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
18

jak przetestować February? To proste :

Kopiuj
LocalDateTime now = LocalDateTime.now();
LocalDateTime nextFebruary = now.withMonth(2).plusYears(1);
long waitTime = ChronoUnit.MILLIS.between(now, nextFebruary);
try { Thread.sleep(waitTime ); } catch (InterruptedException nieBoNie) {}
double wynik = premia.oblicz(4.1d);
.... //asercje

dla innego miesiąca dajesz co innego w withMonth - wybierz najlepiej styczeń (==1), to będziesz krócej czekał.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 4x, ostatnio: jarekr000000
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@impimp94: Nie potrzeba tam czasem ustawić jakieś @RunWith(PowerMockRunner.class)? Inaczej te PrepareForTest i mockStatic nie będą działać.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
CountZero
  • Rejestracja:ponad 7 lat
  • Ostatnio:11 miesięcy
  • Postów:262
0

Ciekawy wpis o tym można znaleźć tutaj - https://www.baeldung.com/java-override-system-time . Do podobnego casu autor zaproponował rozwiązanie korzystające z AOP co jest całkiem pomysłowym rozwiązaniem.

Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 4 godziny
  • Postów:1875
3

Bez sensu. Trzeba ten kod zrefaktorować tak, żeby był testowalny. Jeśli to zadanie rekrutacyjne, to tym bardziej - nikt o zdrowych zmysłach przecież nie będzie sprawdzał czy umiesz w antypatterny :)


”Engineering is easy. People are hard.” Bill Coughran
Shalom
Czemu nie? Może maja dużo takiego kodu, pozwolenia na refaktor nie ma a testy chca zrobić? ;)
Charles_Ray
Jak to nie ma pozwolenia na refaktor? A pozwolenie na programowanie obiektowe chociaż jest? :) refaktor tak jak testy jest nierozłączną częścią tworzenia oprogramowania
Shalom
Wystarczy że masz soft ktory wymaga jakiejś kosztownej certyfikacji i już ją zdobył. Od teraz nie można go ruszać, bo trzeba by certyfikować od nowa., ale może piszesz kolejne narzędzie bazujące na nim, i chcesz mieć dodatkowe testy.
Charles_Ray
Mhm i co nie mogę ruszyć kodu? A jak tam jest jakiś bug, to co wtedy? Nie naprawię, bo certyfikat? Nowy ficzer - nie da się?
Shalom
Adapter, workaround itd ;)
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1

Może chodziło o przetestowanie jak silną psychikę ma rekrutowany?
a) czy zawiesi się jak Sheldon
b) czy zawinie 💩 w sreberko używając PowerMockito
c) czy zna styl Rajesha (patrz post @jarekr000000)
d) czy się uprze że trzeba to zrefaktorować?
e) czy wyjdzie ze spotkania jeśli się nie da?

koszalek-opalek
@vpiotr, @impimp94: Muszę sobie zapisać to zadanie -- bardzo ciekawy sposób sprawdzania, co wart jest programista... :)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.