Dane wyjściowe programu Logcat nie będą widoczne w testach jednostkowych, ponieważ funkcja Logcat ma funkcję Androida - testy JUnit mogą korzystać tylko ze standardowej wersji Java, dlatego funkcje systemu Android nie będą działać.
Co można zrobić w testach jednostkowych, to wstrzyknąć "test podwójny" w testowane komponenty. Ale połączenia Log.x
są statyczne, więc nie można ich przesłonić (bez rozwiązywania np. PowerMocka, którego należy unikać za wszelką cenę).
Dlatego pierwszym krokiem będzie wprowadzenie non-statyczną klasę, która będzie zachowywać jako serwer proxy dla połączeń Log.x
:
/**
* This class is a non-static logger
*/
public class Logger {
public void e(String tag, String message) {
Log.e(tag, message);
}
public void w(String tag, String message) {
Log.w(tag, message);
}
public void v(String tag, String message) {
Log.v(tag, message);
}
public void d(String tag, String message) {
Log.d(tag, message);
}
}
użyć tej klasy w każdym miejscu masz Log.x
połączeń teraz.
Drugi krok byłoby napisać implementację testową-double z Logger
, który przekierowuje do standardowego wyjścia:
public class UnitTestLogger extends Logger{
@Override
public void e(String tag, String message) {
System.out.println("E " + tag + ": " + message);
}
// similar for other methods
}
Ostatnim krokiem jest wstrzykiwać UnitTestLogger
zamiast Logger
w testach jednostkowych:
@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
private Logger mLogger = new UnitTestLogger();
private SomeClass SUT;
@Before
public void setup() throws Exception {
SUT = new SomeClass(/* other dependencies here */ mLogger);
}
}
Jeśli chcesz rygorystycznie przestrzegać pojęć OOP, możesz wydobyć wspólny interfejs dla Logger
i UnitTestLogger
.
Powiedział, że nigdy nie spotkałem się z koniecznością zbadania połączeń Log.x
w testach jednostkowych. Podejrzewam, że ty też tego nie potrzebujesz. Można uruchomić testy jednostkowe w trybie debugowania i krok nad kodem linię po linii debugger, który jest znacznie szybszy niż próbą zbadania wyjście logcat ...
Porady ogólne:
Jeśli kod testujesz zawiera statyczne połączenia Log.x
, a testy jednostek nie powodują awarii - masz problem.
Zgaduję, że albo wszystkie testy są uruchamiane z Robolectric
, albo masz to oświadczenie w build.gradle: unitTests.returnDefaultValues = true
.
Jeśli przeprowadzisz wszystkie testy z Robolectric
, to jest to po prostu nieefektywne, ale jeśli wszystkie połączenia z Androidem zwrócą wartości domyślne, pakiet testowy nie jest niezawodny. Proponuję rozwiązać ten problem, zanim przejdziesz dalej, ponieważ będzie cię gryźć w przyszłości w ten czy inny sposób.
Czy dowiedziałeś się, jak to zrobić? Mam teraz do czynienia z tym samym pytaniem ... –
@IgorGanapolsky, możesz zobaczyć moją odpowiedź poniżej – Vasiliy