W moim kodu mam coś takiego:java: jak wyśmiewać Calendar.getInstance()?
private void doSomething() {
Calendar today = Calendar.getInstance();
....
}
Jak mogę „mock” to w moim testu junit powrotu konkretną datę?
W moim kodu mam coś takiego:java: jak wyśmiewać Calendar.getInstance()?
private void doSomething() {
Calendar today = Calendar.getInstance();
....
}
Jak mogę „mock” to w moim testu junit powrotu konkretną datę?
O ile widzę to masz trzy sensowne opcje:
wstrzyknąć Instancji w dowolnej metody/klasy ustawieniu tego dnia w Calendar
.
private void method(final Calendar cal) { Date today = cal.getTime(); }
Użyj JodaTime zamiast Calendar
. Jest to mniej opcja, a bardziej przypadek sugestii, ponieważ JodaTime ułatwi ci życie. Nadal będziesz musiał wprowadzić ten czas do metody.
DateTime dt = new DateTime();
Date jdkDate = dt.toDate();
Wrap Calendar
wewnątrz jakiegoś interfejsu, który pozwala pobierać czas. Po prostu kpisz z tego interfejsu i odzyskujesz stałą wartość: Date
.
Date today = calendarInterfaceInstance.getCurrentDate()
Klasa 'DateTimeUtils' Joda Time ma statyczne metody, które ustawiają bieżący czas dla wszystkich innych obiektów Joda Time. Jest to bardzo przydatne, aby ustawić czas na określony moment, na przykład do testowania. – Jesper
@Jesper - Tak, to prawda i dobrze, że zapomniałem wspomnieć o – BeRecursive
Dziękuję. Posłuchałem sugestii i przeniosłem się do JodaTime. BTW to łatwo rozwiązuje problem z czymś takim jak: DateTimeUtils.setCurrentMillisFixed (new DateTime (2012, 2, 14, 13, 43, 21) .getMillis()); – Randomize
Nie kpij z niego - zamiast tego wprowadź metodę, którą możesz kpić, która dostaje daty. Coś takiego:
interface Utility {
Date getDate();
}
Utilities implements Utility {
public Date getDate() {
return Calendar.getInstance().getTime();
}
}
Następnie można wstrzyknąć to w swojej klasie lub po prostu użyć klasy pomocnika z grupą metod statycznych z metodą obciążenia dla interfejsu:
public class AppUtil {
private static Utility util = new Utilities();
public static void load(Utility newUtil) {
this.util = newUtil;
}
public static Date getDate() {
return util.getDate();
}
}
Następnie w aplikacji kod:
private void doSomething() {
Date today = AppUtil.getDate();
....
}
Następnie można załadować fałszywy interfejs w swoich metodach testowych.
@Test
public void shouldDoSomethingUseful() {
Utility mockUtility = // .. create mock here
AppUtil.load(mockUtility);
// .. set up your expectations
// exercise the functionality
classUnderTest.doSomethingViaAPI();
// ... maybe assert something
}
Zobacz także Should you only mock types you own? i Test smell - everything is mocked
Napisz klasę o nazwie DateHelper
z metodą getCalendar
zwracającej Calendar.getInstance()
. Zmodyfikuj klasę, którą testujesz, aby zawierała zmienną składową typu DateHelper
, i konstruktor, który wstrzykuje tę zmienną składową. Użyj tego konstruktora w teście, aby wstrzyknąć próbkę o numerze DateHelper
, w której getCalendar
został zgrupowany, aby zwrócić znaną datę.
Możesz sfałszować używając JMockit. Tutaj możesz zobaczyć, jak możesz to zrobić: Mock Java Calendar - JMockit vs Mockito.
Można wyśmiewać go za pomocą PowerMock w połączeniu z Mockito:
Na szczycie swojej klasy:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassThatCallsTheCalendar.class})
Kluczem do sukcesu jest to, że trzeba umieścić klasę w której używasz kalendarz w PrepareForTest zamiast samego kalendarza, ponieważ jest to klasa systemowa. (Ja osobiście miałem szukać dużo wcześniej znalazłem to)
Następnie szydząc sobie:
mockStatic(Calendar.class);
when(Calendar.getInstance()).thenReturn(calendar);
które zależności zawierają dla uzyskania metody mockStatic() działają? –
Przepraszam, powinienem był to powiedzieć. Użyłem importu statycznego do zaimportowania metody mockStatic PowerMockito. Zobacz tę zależność dla powermock mockito: http://mvnrepository.com/artifact/org.powermock/powermock-api-mockito2/1.6.6 – GoGoris
Korzystanie Mockito i PowerMockito:
Calendar endOfMarch = Calendar.getInstance();
endOfMarch.set(2011, Calendar.MARCH, 27);
PowerMockito.mockStatic(Calendar.class);
Mockito.when(Calendar.getInstance()).thenReturn(endOfMarch);
Patrz link dla całego kodu.
Dla tych, którzy następująco MVP wzorzec szyderczy kalendarz jest bułka z masłem:
W Presenter stworzyć metodę, która zwraca instancję kalendarza:
public Calendar getCurrentTime() {
return Calendar.getInstance();
}
W widoku (aktywność, Fragment itp.) Można uzyskać dostęp do kalendarza za pomocą prezentera:
Calendar calendar = mPresenter.getCurrentTime();
// do whatever you want
w badaniach zrobić:
// create a dummy calendar
Calendar mockCalendar = ...
// You've already mocked your Presenter, haven't you?
when(mMockPresenter.getCurrentTime()).thenReturn(mockCalendar);
// here you are!
Ta linia nie może być kompilacji! – adarshr
Czy 'today' jest członkiem klasy (pole) lub zmienną lokalną wewnątrz metody? –
zmienna lokalna wewnątrz metody – Randomize