2015-08-10 16 views
7

Ho bisogno di prendere in giro alcune classi personalizzate (creane un'ombra). Ho già letto su http://robolectric.org/custom-shadows/ come fare questo.Come creare ombre personalizzate in robolectric 3.0?

così, ho qualche classe:

public class MyClass { 

    public static int regularMethod() { return 1; } 
} 

creo un'ombra:

@Implements(MyClass.class) 
public class MyShadowClass { 

    @Implementation 
    public static int regularMethod() { return 2; } 
} 

E ho impostato l'ombra in Test-classe:

@RunWith(RobolectricGradleTestRunner.class) 
@Config(constants = BuildConfig.class, shadows={MyShadowClass.class}) 
public class MyTest { 

    @Test 
    public void testShadow() { 
     assertEquals(2, MyClass.regularMethod()); 
    } 
} 

Ma l'ombra non è usato

java.lang.AssertionError: 
Expected :2 
Actual :1 

Come rendere visibile qualsiasi ombra personalizzata per RobolectricGradleTestRunner?

ho già provato:

  1. http://www.codinguser.com/2015/06/how-to-create-shadow-classes-in-robolectric-3/
  2. https://github.com/jiahaoliuliu/RobolectricSample/blob/master/app-tests/src/main/java/com/jiahaoliuliu/robolectricsample/RobolectricGradleTestRunner.java
  3. Mock native method with a Robolectric Custom shadow class

ma io ottenere vari errori di compilazione, come ad esempio

  • InstrumentingClassLoaderConfig non trovato
  • Setup non trovato

come utilizzare le ombre personalizzati correttamente in robolectric 3.0?

+0

Di solito avvolgiamo metodi statici in classi proprie o metodi protetti che potremmo prendere in giro nei test –

risposta

4

Le ombre personalizzate devono essere evitate e devono essere un ultimo rifugio. Dovrebbe essere usato solo se non puoi fare molto refactoring nel tuo codice che ti impedisce di eseguire i tuoi test come una chiamata di metodo nativa. È meglio deridere l'oggetto di quella classe o spia usando powermock o mockito piuttosto che l'ombra personalizzata. Se si tratta di un metodo statico, quindi utilizzare powermock.

Nel nostro progetto, avevamo una classe con alcuni metodi nativi ed era la classe di configurazione utilizzata ovunque nell'app. Quindi abbiamo spostato i metodi nativi in ​​un'altra classe e l'abbiamo ombreggiato. Quei metodi nativi stavano fallendo i casi di test.

In ogni modo ecco come si può personalizzato ombra in robolectric 3.0:

Creare un test runner personalizzato che si estende RobolectricGradleTestRunner:

public class CustomRobolectricTestRunner extends RobolectricGradleTestRunner { 


public CustomRobolectricTestRunner(Class<?> klass) throws InitializationError { 
    super(klass); 
} 

public InstrumentationConfiguration createClassLoaderConfig() { 
    InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder(); 
    builder.addInstrumentedPackage("com.yourClassPackage"); 
    return builder.build(); 
} 

Assicurarsi che che il pacchetto non contiene casi di test che si sono in esecuzione usando robolectric.

1

I am Jiahao, il creatore del secondo repository a cui ti riferisci.

Prima di tutto grazie per controllare il mio codice. Faccio molte ricerche su Android e sono felice che la mia ricerca sia utile per qualcun altro.

Quindi, l'ombra su Robolectric. Sto usando Robolectric 3.1 in questo progetto, per verificare come Robolectric 3 funziona con Marshmallow: https://github.com/jiahaoliuliu/robolectricForMarshmallow

Ho testato la nuova autorizzazione Runtime Manager, così come shadowing delle applicazioni e attività.

Ecco il codice di esempio dell'attività ombra:

import android.content.Context; 
import com.jiahaoliuliu.robolectricformarshmallow.controller.MainController; 
import org.robolectric.annotation.Implementation; 
import org.robolectric.annotation.Implements; 

/** 
* Created by Jiahao on 7/18/16. 
*/ 
@Implements(MainController.class) 
public class MainControllerShadow { 

    public void __constructor__ (Context context) { 
     // Not do anything 
    } 

    @Implementation 
    public String getTextToDisplay(boolean permissionGranted) { 
     return "Test"; 
    } 
} 

https://github.com/jiahaoliuliu/robolectricForMarshmallow/blob/master/app/src/test/java/com/jiahaoliuliu/robolectricformarshmallow/shadow/MainControllerShadow.java

e questo è come Io lo utilizzo nel test di unità:

pacchetto com.jiahaoliuliu.robolectricformarshmallow;

import com.jiahaoliuliu.robolectricformarshmallow.shadow.MainControllerShadow; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.robolectric.Robolectric; 
import org.robolectric.RobolectricGradleTestRunner; 
import org.robolectric.annotation.Config; 

import static org.junit.Assert.*; 

/** 
* Created by Jiahao on 6/30/16. 
*/ 
@RunWith(RobolectricGradleTestRunner.class) 
@Config(constants = BuildConfig.class, manifest = Config.NONE, application = FoolApplication.class, 
    shadows = { MainControllerShadow.class}, sdk = 18) 
public class MainActivityTest { 

    private MainActivity mMainActivity; 

    @Before 
    public void setUp() throws Exception { 
     mMainActivity = Robolectric.setupActivity(MainActivity.class); 
    } 

    @After 
    public void tearDown() throws Exception { 

    } 

    @Test 
    public void testOnCreate() throws Exception { 
     // Simple test to know that it works 
     assertTrue(true); 
    } 
} 

https://github.com/jiahaoliuliu/robolectricForMarshmallow/blob/master/app/src/test/java/com/jiahaoliuliu/robolectricformarshmallow/MainActivityTest.java

Come potete vedere, non sto usando personalizzato Gradle test Runner. Ho controllato il codice sorgente di Robolectric, per la versione 3.0 e 3.1 (ultima) è sufficiente per specificare solo le classi shadow nell'intestazione.

Spero che sia d'aiuto

Problemi correlati