2017-08-15 37 views
1

我有這樣一個單:如何用Robolectic來影響單身人士?

public class SingletonA{ 

     private SingletonA instance = null; 

     private SingletonA(){ 
     } 

     public static SingletonA getInstance(){ 
      return instance ; 
     } 

     public static void init(){ 
      System.loadLibrary("alib"); 
      instance = new SingletonA(); 
     } 

     ...... 
     other methods 
} 

正如你所看到的,使用它之前,我必須調用SingletonA.init(),但Robolectric無法加載。所以文件。我想寫一個ShadowSingletonA來替換它,但不知道該怎麼做。因爲變量實例是私有的。任何人都可以幫忙嗎?另外,SingletonA類來自第三方庫,所以我不能對它做任何修改。

回答

0

另一種常見的方式來處理你的依賴關係抽象他們,使他們可互換和可測試。

所以假設你有下一個API偉大的圖書館:

​​

首先,創建抽象:

public class LibraryGenericPurpose { 
    public void doSomeThing(@NonNull String nameOfThing) { 
     LibraryName.getInstance().doSomething(new Event(nameOfThing)); 
    } 
} 

首先要注意的方法也不是一成不變的,所以你必須添加一個額外的依賴於你只是從庫中調用靜態方法的所有地方。有時候爲這樣的事物設置接口也很方便。

現在你改變一個地方,你使用它:

class SomeClass { 
    public void someMethod() { 
     LibraryName.getInstance().doSomething(new Event(nameOfThing)); 
    } 
} 

到:

class SomeClass { 
    @NonNull private LibraryGenericPurpose library; 

    public SomeClass(@NonNull LibraryGenericPurpose library) { 
     this.library = library; 
    } 

    public void someMethod() { 
     library.doSomeThing("Great!"); 
    } 
} 

如果你沒有在班級的生命週期ActivityFragment然後控制你必須學習如何注入依賴關係的新方法。

最後,在測試中,您根本不需要使用Robolectric作爲SomeClass。很多時候,這些類如LibraryGenericPurpose不能在JVM上測試(即使是在Robolectric),在儀器測試中很難或不可能測試。

+0

好的,這對我的代碼來說似乎是一場革命。 –

0

這是我的方法,使其可測試。 我們主要在應用程序類中初始化第三方庫。在某種程度上:

public class MyApplication { 
    public void onCreate() { 
    initSomeLibrary(); 
    } 

    @VisibleForTests 
    @RestrictTo(RestrictTo.Scope.TESTS) 
    protected void initSomeLibrary() { 
    SomeLibrary.init(this); 
    } 
} 

Robolectric總是會嘗試加載在你的清單中指定,除非你是做應用:所以

  1. Add @Config where you defined another app class name
  2. You put in test folder in the same package app class that has name Test

兩個情況下,您必須創建自定義應用程序應用程序從歷史上看,第一個選項早些時候可用,所以我堅持下去。但是,它需要大約Robolectric知識,所以我把我的測試應用程序類@Config部分現在(所以測試不需要了):

public class TestMyApplication { 
    protected void initSomeLibrary() { 
     //nothing to do 
    } 
} 
+0

是的,我已經在我的UT病例中使用了自定義應用程序來避免加載「.so」文件。但是最近,我得到了一個名爲EZOpenSDK的單例模式的類,它在其構造函數中運行** System.loadLibrary()**。這讓我在UT中創建了這個類的一個實例。所以我想創建一個ShadowEZOpenSDK來替換它。但是我不知道如何在我的ShadowEZOpenSDK中處理方法** public static EZOpenSDK getInstance()**。 –

+0

然後我會寫另一個答案:) –

+0

這真是太好了。 –