2013-03-09 5 views
12

Stworzyłem nowy testowy projekt Androida. Pobrałem powermock-mockito-junit-1-1.5.zip z https://code.google.com/p/powermock/downloads/list. Dodałem wszystkie biblioteki do folderu projektu testowego w wersji libs. Klasa testowa jest bardzo prostym obiektem:Jak korzystać z PowerMock w projektach Android?

package com.test.test; 

import org.junit.runner.RunWith; 
import org.powermock.modules.junit4.PowerMockRunner; 

import android.util.Log; 

@RunWith(PowerMockRunner.class) 
public class TestTestAndroid { 

    public void testRuns() { 
     Log.e("test", "Test case is called"); 
    } 
} 

Następnie próbuję uruchomić projekt z Eclipse lub utworzyć projekt z wiersza poleceń. Mam ten sam błąd:

Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lorg/hamcrest/Description;

Jak się okazuje, zarówno junit-4.8.2.jar i mockito-all-1.9.5.jar zdefiniowania org.hamcrest.Description. Muszę dodać słoik Mockito z oczywistych powodów - potrzebuję Mockito. Inna wersja JUnit jest dostarczana przez Androida, ale jest to stara wersja, która nie zawiera adnotacji @RunWith.

Czy ktoś może odpowiedzieć na pytanie, w jaki sposób korzystać z powermock i mockito w projekcie Android, bez konfliktu z org.hamcrest.Description?

Odpowiedz

10

Niestety, nie można używać PowerMock w VM Dalvik.

PowerMock działa, uruchamiając test w niestandardowej klasie ClassLoader, która używa Javassist do modyfikacji kodu bajtowego klas. Działa to dobrze na normalnej maszynie JVM, ale na Dalvik kod bajtowy i format klasy są różne, więc to podejście nie działa. PowerMock musiałby zostać przepisany, aby używać Dexmaker zamiast Javassist - byłoby to zdecydowanie nietrywialne i nie widzę czegoś takiego na PowerMock issues list.

+0

Jeśli nie można używać PowerMock na Androida, wiesz jakikolwiek inny sposób na umieszczenie statycznej metody w systemie Android? – lowellk

+5

@lowellk Istnieje obejście problemu. Niech metoda niestatyczna wywoła metodę statyczną, a następnie ją zatknie. Na przykład, jeśli 'HttpConstants.getUrl()' jest metodą statyczną, napisz inną metodę: 'String getUrl() {return HttpConstants.getUrl(); } 'Następnie możesz zamknąć tę metodę. –

+0

+1 za wskazówkę @ MattQuigley –

8

W rzeczywistości uważam, że jest to całkowicie nieprawdziwe (przynajmniej z najnowszą wersją).

W moim Gradle konfiguracji dla modułu gdzie chcę przetestować mojego kodu mam

// Mockito and PowerMock 
androidTestCompile ('org.powermock:powermock-mockito-release-full:1.6.0') { 
    exclude module: 'hamcrest-core' 
    exclude module: 'objenesis' 
} 

i wszystko działa poprawnie. Tak długo, jak używać:

@RunWith(PowerMockRunner.class) @PrepareForTest(ClassToMock.class) 

opisywanie moją klasę (np nie można go uruchomić z Robolectric, nadal dobrze w środowiskach CI)

+1

Czy możesz przesłać swoją pełną wersję gradle? Nie mogę znaleźć importu dla PowerMockRunner.class –

+0

Niestety, nie mogę, ponieważ jest częścią aplikacji naszej firmy, ale powinien tam być, zaimportuj 'import org.powermock.modules.junit4.PowerMockRunner;' po prostu upewnij się jeśli używasz androidTestCompile, twoje testy oprzyrządowania używające tego importu są w folderze androidTest, itd. – AllDayAmazing

+0

ok, ale aby mieć ten import, muszę mieć następujące kompile w gradle: androidTestCompile 'org.powermock: powermock-module-junit4: 1.6.2 ' Powoduje to wiele problemów, takich jak: "Zdefiniowano wiele plików dex ..." –