2015-01-15 2 views
3

Я пытаюсь настроить тестовую среду для моего проекта Android. Базовая установка Robolectric выполнена. Я использовал этот красивый tutorial. Если я прокомментирую SugarORM в моем Manifest.xml, все тесты работают нормально. Но если я хочу использовать его с SugarORM, я всегда получаю эту ошибку:Тестирование с помощью SugarORM и Robolectric

java.lang.NullPointerException at dalvik.system.DexFile$DFEnum.hasMoreElements(DexFile.java:239) at com.orm.SugarDb.getDomainClasses(SugarDb.java:37) at com.orm.SugarDb.createDatabase(SugarDb.java:104) at com.orm.SugarDb.onCreate(SugarDb.java:100) at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252) at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164) at com.orm.Database.getDB(Database.java:18) at com.orm.SugarApp.onTerminate(SugarApp.java:16) at org.robolectric.internal.ParallelUniverse.tearDownApplication(ParallelUniverse.java:133) at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:246) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

Есть ли у всех одинаковые проблемы?

Редактировать

Может быть, это, потому что Robolectric выключение после испытания и sugarorm еще не закончена. Мой TestClass

@RunWith(RobolectricTestRunner.class) 
@Config(manifest="./src/main/AndroidManifest.xml",emulateSdk=18) 
public class MyActivityTest{ 

    private ActivityController<OnLogActivity> controller = Robolectric.buildActivity(OnLogActivity.class).create().setup(); 

    @Test 
    public void clickingLogin_shouldStartLoginActivity() { 
     OnLogActivity activity = controller.get(); 
     assertTrue(activity.findViewById(R.id.login) instanceof Button); 

    } 

} 

Edit 2,0:

Это Robolectric может найти android:name=com.orm.SugarApp вы должны создать testfolder с тем же пакетом com.orm и добавить тестовый класс под названием TestSugarApp. После этого вы можете проверить все.

package com.orm; 

... 

@RunWith(RobolectricTestRunner.class) 
@Config(manifest="./src/main/AndroidManifest.xml",emulateSdk=18) 
public class TestSugarApp extends Application 
     implements TestLifecycleApplication { 

    private ActivityController<OnLogActivity> controller; 


    @Test 
    public void startEverTestSugarAppAsFirst() { 

    } 

    @Override 
    public void beforeTest(Method method) { 
     Log.v("test", "beforeTest"); 
    } 

    @Override 
    public void prepareTest(Object test) { 
     Log.v("test", "prepareTest"); 
    } 

    @Override 
    public void afterTest(Method method) { 
     Log.v("test", "afterTest"); 
    } 
} 
+0

У вас есть специальный код в вашем классе App onTerminate? –

+0

У меня есть только ondestroy в своей деятельности. Сахарник загружается прямо перед приложением. Потому что я установил приложение android: name to sugarorm – loose11

+1

Исправление для этого в релизе 1.4 beta – David

ответ

5

Ok попробуйте следующий. Добавить следующий класс вам проверить код:

public class TestSugarApp 
    extends SugarApp 
{ 
    @Override 
    public void onCreate() {} 

    @Override 
    public void onTerminate() {} 
} 

Класс с именем Test будет загружен и используется Robolectric, и вы можете изменить некоторые вещи, которые не относятся к тестированию. Я пытаюсь предотвратить выполнение кода от SugarApp в onCreate и onTerminate (https://github.com/satyan/sugar/blob/master/library/src/com/orm/SugarApp.java).

+0

Спасибо. Я попробовал, но программа разбилась. Я решил проблему. :) Посмотрите на первое сообщение :) – loose11

+0

Если да, то пожалуйста, примите ответ. Вы действительно хотите провести там тест (в этом классе)? –

+0

Я должен, в противном случае это не работает – loose11

1

@ Ответ Евгения Мартынова работает отлично (спасибо большое!). Однако, когда вы расширили андроид.app.Application самостоятельно (который, в свою очередь, расширяет SugarApp), вы также исключите свой собственный код.

Я решил эту проблему с помощью этого кода:

Класс Application в тестовом коде (в отличие от ответа Eugen в):

public class TestApp extends App { 
    /** Prevents onCreate() and onTerminate() to call their super (in which {@link com.orm.SugarApp} is initialized) */ 
    @Override 
    protected boolean callSuper() { 
     return false; 
    } 
} 

Мой собственный класс Application (расширение SugarApp):

public class App extends com.orm.SugarApp { 
    private static Context context; 

    public static Context getContext() { 
     return context; 
    } 

    @Override 
    public void onCreate() { 
     if (callSuper()) { 
      super.onCreate(); 
     } 

     // My own code is always executed, also during unittests 
     context = getApplicationContext(); 
    } 

    @Override 
    public void onTerminate() { 
     if (callSuper()) { 
      super.onTerminate(); 
     } 
    } 

    protected boolean callSuper() { 
     return true; // Super is executed by default 
    } 
} 

Я согласен, что это выглядит не очень красиво (любой АДВИ это сделать лучше?), но он отлично работает для меня!

пс. Я объявил свой класс приложений в своем манифесте следующим образом:

<application 
    android:name=".App" 
Смежные вопросы