2015-01-15 7 views
3

내 안드로이드 프로젝트를위한 테스트 환경을 설정하려고합니다. 기본 Robolectric 설정이 완료되었습니다. 이 멋진 tutorial을 사용했습니다. Manifest.xml에서 SugarORM을 주석 처리하면 모든 테스트가 정상적으로 작동합니다. 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)

모두에게 동일한 문제가 있습니까? 테스트 및 sugarorm 후 Robolectric 종료가 아직 완료되지 않았기 때문에

편집

은 어쩌면이다. 내 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); 

    } 

} 

편집 2.0 :

Robolectric 찾을 수있는 android:name=com.orm.SugarApp 당신이 TestSugarApp라는 테스트 클래스를 com.orm의 동일한 패키지에 testfolder를 작성하고 추가해야합니다. 그 후에 모든 것을 테스트 할 수 있습니다.

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

응용 프로그램 클래스 onTerminate에 특별한 코드가 있습니까? –

+0

나는 활동 중에 오직 온 데스트로만을 가지고있다. 설탕은 앱 바로 전에로드됩니다. 나는 applroid : name을 sugarorm에 설정했기 때문에 – loose11

+1

이 문제는 1.4 베타 릴리스에 있습니다 – David

답변

5

다음을 시도하십시오. 당신이 코드를 테스트하려면 다음 클래스를 추가

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

    @Override 
    public void onTerminate() {} 
} 

테스트로드 Robolectric에서 사용하고 테스트 관련이없는 몇 가지를 재정의 할 수 있습니다됩니다라는 이름의 클래스입니다. SugarApp에서 onCreateonTerminate (https://github.com/satyan/sugar/blob/master/library/src/com/orm/SugarApp.java)의 코드를 실행하지 못하게하려고합니다.

+0

고마워요. 나는 그것을 시도했지만 프로그램이 추락했다. 나는 그 문제를 해결했다. :) 첫 번째 게시물을보세요 :) – loose11

+0

만약 그렇다면 답변을 수락하십시오. 당신은 정말로이 반에서 시험을하고 싶습니까? –

+0

필자는 그렇지 않으면 작동하지 않습니다 – loose11

1

@Eugen Martynov의 답변은 완벽하게 작동합니다 (감사합니다!). 그러나 android.app.Application을 직접 확장하면 (SugarApp가 확장 됨) 자체 코드가 제외됩니다.

이 코드 사용하여이 문제를 해결했습니다

(오이겐의 대답 반대) 테스트 코드에서 Application 클래스 :

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

내 자신의 응용 프로그램 클래스 (확장 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 
    } 
} 

매우 아름답지 않다는 데 동의합니다 (모든 advi ce는 이것을 더 좋게 만드는 것인가?). 그러나 그것은 나를 위해 완벽하게 작동한다!

ps. 내 매니페스트에서 내 응용 프로그램 클래스를 다음과 같이 선언했습니다.

<application 
    android:name=".App" 
관련 문제