2017-02-02 9 views
3

私の仕事は、既存のAndroidアクティビティの単体テストを書くことであり、コードはユニットテスト(タイトカップリング)に準拠するように書かれていません。robolectric - アクティビティオブジェクトを作成中にビジネスクラスを模擬して注入する方法

シナリオ:私はMyActivity onCreateメソッド内でインスタンス化されているクラスStroageManagerを持っています。

@Override 
protected void onCreate(Bundle savedInstanceState) 
{    
StorageManager storagemanager = GetStorageManager(); // return new object of stroage manager 
super.onCreate(savedInstanceState);..... 
    ... 
} 

Robolectricを使用してアクティビティのインスタンスを作成するには、MyActivityを設定する前にテスト内でモックする必要があります。

問題:あざけりとrobolectric

注意通じmyActivityオブジェクトを作成しながら、このモックオブジェクトを注入する方法:これは、既存のされ活動をし、私は大規模な拡張にアクティビティコードを変更するために多くの自由を持っていません。また、Mockitoフレームワークを使用してMockitoを使用していますので、Mockitoを使用して例を挙げると素晴らしいでしょう。

@RunWith(RobolectricTestRunner.class) 
public class myActivityTest { 

    @Mock 
    private StorageManager storageManager; 

    @InjectMocks 
    MyActivity myActivity; 

    @Before 
    public void setUp() { 
     ActivityController<MyActivity> activityController = Robolectric.buildActivity(MyActivity.class); 
     myActivity = activityController.get(); 
     // when(registrationActivity.GetMetricManager()).thenReturn(mock(MetricsManager)); 
     initMocks(this); 
     activityController.setup();   
    } 

}


私は解決策は、以下の提案試してみましたが、今、私は取得しています:ここで

は、私はMockitoとRobolectricを使用しようとするが、それは仕事に失敗した私のサンプルコードですこのエラーは

私が提案したとおりに自分のコードを変更しました。これはエラーを投げかけています。この行を実行している間ActivityController activityController = Robolectric.buildActivity(TestMyActivity.class);

java.lang.RuntimeException:java.lang.NoSuchMethodException:テスト$ TestMyActivity()

at org.robolectric.util.ReflectionHelpers.callConstructor(ReflectionHelpers.java:233) 
    at org.robolectric.util.ActivityController.of(ActivityController.java:27) 
    at org.robolectric.Robolectric.buildActivity(Robolectric.java:42) 
    at Tests$TestMyActivity.setUp(RegistrationTest.java:89) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) 

答えて

3

StorageManagerはフィールドではないか、コンストラクタで渡されたので、@InjectMocksはどんな効果を持っていないことを第一に。

私はより良いDIを使用するために活動をリファクタリングだろうが、簡単な勝利は、次のようになります。

public class MyActivity extends ... { 
    @VisibleForTest 
    @RestrictTo(Scope.TESTS) 
    protected StorageManager GetStorageManager() { 
     ... 
    } 
} 

@RunWith(RobolectricTestRunner.class) 
@Config(constants = BuildConfig.class) 
public class MyActivityTest { 
    @Mock 
    private StorageManager storageManagerMock; 

    MyActivity myActivity; 

    @Before 
    public void setUp() { 
     initMocks(this); 
     ActivityController<TestMyActivity> activityController = Robolectric.buildActivity(TestMyActivity.class); 
     myActivity = activityController.get(); 
     // when(registrationActivity.GetMetricManager()).thenReturn(mock(MetricsManager)); 
     activityController.setup();   
    } 

... 

    public class TestMyActivity extends MyActivity { 
     protected StorageManager GetStorageManager() { 
      return storageManagerMock; 
     } 
    } 
} 

これは小さな変更で動作するはずです。

+0

私が提案したコードを修正しました。これはエラーを投げています。 buildActivityメソッドを実行中 – AvtarSohi

+0

お返事ありがとうございます@、しかし、私はまだあなたの提案に従う間にエラーが発生しています。私はフィールドにメソッドを変更することができるので何も特別なことは何もないので、メソッドの代わりにセッターとゲッターを使うことができるので、@ InjectMocksの解決策を提案できますか? – AvtarSohi

+0

おそらくアクティビティクラスは静的であるべきです –

関連する問題