其他分享
首页 > 其他分享> > android-robolectric-如何在创建Activity对象时模拟和注入业务类

android-robolectric-如何在创建Activity对象时模拟和注入业务类

作者:互联网

我的任务是为现有的Android活动编写单元测试,并且未编写符合单元测试(紧密耦合)的代码.

场景:我有一个StroageManager类,该类正在MyActivity onCreate方法中实例化.

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

为了通过Robolectric创建活动实例,我需要在测试中在设置MyActivity之前对其进行模拟.

问题:如何通过robolectric创建myActivity对象时如何模拟和注入该模拟对象

注意:这是现有的Activity,我没有很大的自由来修改Activity代码以进行大范围扩展.另外,我们正在使用Mockito框架进行模拟,因此,如果您使用Mockito进行示例,那将很棒.

这是我尝试在Mockito中使用Robolectric的示例代码,但无法正常工作:

@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();         
    }

}

我已经尝试过以下建议的解决方案,但是现在出现此错误:

我已经按照您的建议修改了我的代码,并抛出以下错误.在执行此行时ActivityController activityController = Robolectric.buildActivity(TestMyActivity.class);

java.lang.RuntimeException:java.lang.NoSuchMethodException:Tests $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)

解决方法:

首先,StorageManager不是字段或构造函数传递的字段,因此@InjectMocks没有任何作用.

我将重构Activity以使用更好的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;
      }
   }
}

这应该进行较小的修改.

标签:unit-testing,mockito,android-testing,robolectric,android
来源: https://codeday.me/bug/20191111/2022191.html