2015-08-10 18 views
7

Ich muss einige benutzerdefinierte Klasse spotten (erstellen Sie dafür einen Schatten). Ich habe bereits gelesen auf http://robolectric.org/custom-shadows/, wie dies zu tun ist.Wie erstelle ich benutzerdefinierte Schatten in robectric 3.0?

so habe ich einige Klasse:

public class MyClass { 

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

Ich schaffe einen Schatten:

@Implements(MyClass.class) 
public class MyShadowClass { 

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

Und ich den Schatten in Test-Klasse:

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

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

Aber der Schatten ist nicht benutzt.

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

Wie kann man einen benutzerdefinierten Schatten für RobolectricGradleTestRunner sichtbar machen?

Ich habe bereits versucht:

  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

aber ich verschiedene Kompilierungsfehlern bekommen, wie

  • InstrumentingClassLoaderConfig nicht
  • Setup nicht
  • gefunden

wie benutzerdefinierte Schatten in robolectric 3.0 richtig zu benutzen?

+0

Wir wickeln in der Regel statische Methoden in eigenen Klassen oder geschützten Methoden, die wir in Tests verspotten konnten –

Antwort

4

Benutzerdefinierte Schatten sollten vermieden werden und müssen ein letzter Ausweg Resort sein. Es sollte nur verwendet werden, wenn Sie in Ihrem Code nicht viel Refactoring durchführen können, was verhindert, dass Sie Ihre Tests wie einen nativen Methodenaufruf ausführen. Es ist besser, das Objekt dieser Klasse zu verspotten oder mit powermock oder mockito auszuspionieren, als es mit Schatten zu tun. Wenn es sich um eine statische Methode handelt, verwenden Sie powermock.

In unserem Projekt hatten wir eine Klasse, die einige native Methoden hatte und es war die Config-Klasse, die überall in der App verwendet wurde. Also haben wir die nativen Methoden in eine andere Klasse verschoben und haben dies beschattet. Diese nativen Methoden haben die Testfälle nicht bestanden.

Sowieso ist hier, wie Sie benutzerdefinierte in robolectric 3.0 Schatten kann:

eine benutzerdefinierte Testläufer erstellen, die RobolectricGradleTestRunner erweitert:

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(); 
} 

Stellen Sie sicher, dass das Paket keine Testfälle enthält, die Sie laufen mit robolectric.

1

Ich bin Jiahao, der Schöpfer des zweiten Repository, das Sie beziehen.

Zunächst einmal danke, um meinen Code zu überprüfen. Ich mache viele Recherchen über Android und freue mich, dass meine Forschung für jemand anderen nützlich ist.

Dann der Schatten über Robolectric. Ich verwende Robolectric 3.1 in diesem Projekt zu testen, wie Robolectric 3 mit Marshmallow funktioniert: https://github.com/jiahaoliuliu/robolectricForMarshmallow

ich die neuen Runtime Permission-Manager sowie Shadowing Anwendung und Aktivitäten getestet habe. Hier

ist Beispielcode der beschatteten Aktivität:

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

Und das ist, wie ich es in der Unit-Test bin mit:

Paket 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

Wie Sie sehen, ich bin mit Test-Runner nicht angepasst Gradle. Ich habe den Quellcode von Robolectric überprüft, für Version 3.0 und 3.1 (neu) ist es gut genug, nur die Schattenklassen in der Kopfzeile anzugeben.

Ich hoffe, es hilft