2015-04-14 83 views
10

我試圖用Robolectric創建一個測試。我的目標是能夠從一個自定義行爲中替換一個類的功能(例如來自一個庫,我無法修改代碼)。Robolectric陰影不起作用

我創造了這個小測試,模擬什麼,我想做的事:

@RunWith(RobolectricTestRunner.class) 
@Config(shadows = {ShadowMessenger.class}) 
public class TestShadow { 

    @Test 
    public void testMessenger() { 
     OriginalMessenger messenger = new OriginalMessenger(); 
     String message = messenger.getMessage(); 
     Assert.assertEquals("Shadow messenger", message); 
    } 

    public static class OriginalMessenger { 

     public String getMessage() { 
      return "Original messenger"; 
     } 
    } 

    @Implements(OriginalMessenger.class) 
    public static class ShadowMessenger extends OriginalMessenger { 

     @Implementation 
     public String getMessage() { 
      return "Shadow messenger"; 
     } 
    } 
} 

在這個例子中,OriginalMessenger是在圖書館,並提供一個默認功能的類。並且ShadowMessenger是包含我想要應用的自定義行爲的類,只要我使用OriginalMessenger

但是,當我運行測試失敗。 消息的內容是「原始使者」。彷彿ShadowMessenger從未使用過。

我在做什麼錯?

+2

爲什麼要製造一個影子?爲什麼不「模擬」或「存根」呢? –

+0

如何使用模擬和存根實現相同的結果? –

+0

哦,我看到nenick解決了你的問題?你可以使用EasyMock/PowerMock來模擬你的課堂或Spock(Robospock)。看看這裏的例子:https://github.com/jaredsburrows/BurrowsAppsExamples/blob/master/Lib-BurrowsApps/src/test/java/burrows/apps/example/lib/utils/PlayServicesUtilsTest.java。 –

回答

14

原來你只能投影android類。但是通過一個自定義的robolectric測試運行器,你也可以爲自己的課程蒙上陰影。

Robolectric 3.1.4(RobolectricGradleTestRunner被完全除去,因此需要重寫在RobolectricTestRunner下面描述的方法)

@Override 
protected ShadowMap createShadowMap() { 
    return new ShadowMap.Builder() 
     .addShadowClass(OriginalMessenger.class, ShadowMessenger.class, true, true, true) 
     .build(); 
} 

Robolectric 3.0

@Override 
public InstrumentationConfiguration createClassLoaderConfig() { 
    InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder(); 
    builder.addInstrumentedClass(OriginalMessenger.class.getName()); 
    return builder.build(); 
} 

Robolectric 2.4

@Override 
protected ClassLoader createRobolectricClassLoader(Setup setup, SdkConfig sdkConfig) { 
    return super.createRobolectricClassLoader(new ExtraShadows(setup), sdkConfig); 
} 

class ExtraShadows extends Setup { 
    private Setup setup; 

    public ExtraShadows(Setup setup) { 
     this.setup = setup; 
    } 

    public boolean shouldInstrument(ClassInfo classInfo) { 
     boolean shoudInstrument = setup.shouldInstrument(classInfo); 
     return shoudInstrument 
       || classInfo.getName().equals(OriginalMessenger.class.getName()); 
    } 
} 

示例項目https://github.com/nenick/android-gradle-template/

+0

不錯!不知道 –

+5

有很多無證的功能;) – nenick

+0

如果我這樣做,我得到一個StackOverflowError。你知道它爲什麼會發生嗎? –