robolectric 3.0 Mockito - 如何模拟课堂内的活动

时间:2015-09-22 03:31:09

标签: mocking robolectric android-testing

我正在迁移到robolectric 3.0

问题陈述 -

我有一个AppUtility类,它在MyActivity中实例化,所以为了检查它的方法被调用,我需要在设置MyActivity之前在我的测试中模拟它。

这是我的代码:

@Mock
private AppUtility mockAppUtility;

@Before
public void setUp() {
    initMocks(this);
    myActivity= Robolectric.setupActivity(MyActivity.class);
    equalsButton = (Button) myActivity.findViewById(R.id.equals_sign);
    shadowActivity = Shadows.shadowOf(myActivity);
}

以下是测试方法: -

  @Test
        public void shouldCallStartAlarm() {
            for (int i = 0; i < 4; i++) {
                equalsButton.performClick();
            }
            verify(mockAppUtility).startAlarm();
        }

我得到以下错误信息: - 哪个show mock没有链接到活动,我怎么能将它绑定到活动?

Actually, there were zero interactions with this mock.

但是模拟对象与测试无关。在早期版本的Robolectric中,我使用关联模拟对象来创建活动,通过覆盖它来如下

 myActivity = new MyActivity() {
                @Override
                AppUtility getUtil() {
                    return mockAppUtility;
                }
            };
            myActivity.onCreate(new Bundle());

并且使用Robolectric 3.0可以正常工作,如何在开始活动之前绑定模拟对象。

关注@nenick您的第二个选项:它的外观如何

    @Mock
    private AppUtility appUtility;
    @InjectMocks
    private MyActivity myActivity;
    @Before
    public void setUp() {
        ActivityController<MyActivity> activityController = Robolectric.buildActivity(MyActivity.class);
//      myActivity= Robolectric.setupActivity(MyActivity.class);
        myActivity=activityController.get();
        initMocks(this);
        activityController.setup();
        equalsButton = (Button) myActivity.findViewById(R.id.equals_sign);
//      shadowActivity = Shadows.shadowOf(calculatorActivity);
    }

但我得到了异常: -

java.lang.IllegalArgumentException: attempted to invoke public final android.app.Application org.robolectric.shadows.ShadowActivity.getApplication() on instance of class org.com.android.AppUtility$$EnhancerByMockitoWithCGLIB$$77c74666, but AppUtility$$EnhancerByMockitoWithCGLIB$$77c74666 doesn't extend ShadowActivity
  

它在步骤中断 - activityController.setup();

2 个答案:

答案 0 :(得分:4)

使用mockito模拟注入功能设置模拟很容易。

@Mock
private AppUtility mockAppUtility;

@InjectMocks
Activity mActivity;

@Before
public void setUp() {
  myActivity= Robolectric.setupActivity(MyActivity.class);
  equalsButton = (Button) myActivity.findViewById(R.id.equals_sign);
  shadowActivity = Shadows.shadowOf(myActivity);

  // create and injects mocks into object annotated with @InjectMocks
  initMocks(this);
}

要在调用活动设置(onCreate,...)之前设置模拟,您必须在安装前访问您的活动。

@Before
public void setUp() {
  ActivityController<Activity> activityController = Robolectric.buildActivity(Activity.class);

  // get the activity instance 
  mActivity = activityController.get()

  initMocks(this);

  // now setup your activity after mock injection
  activityController.setup()
}

答案 1 :(得分:0)

单元测试的主要规则之一 - 从不在测试下模拟类。您可能会spy,但这又是一次救援挑战,在这种情况下你不应该使用它。

另一个smell显示您已经进行了唤醒测试 - 当您能够成功运行此测试时,它将无法保证真正的警报设置。它只保证调用此方法。所以最好验证set alrams而不是验证方法调用。检查this link以查看阴影警报管理器

的使用示例