如何在Android中模拟(或)测试方法级别的变量?

问题描述 投票:1回答:2

我上了这样的课,

class MyIntentProvider {
    public Intent provideIntent(final Context context) {
        final Intent intent = new Intent();
        intent.setAction(MY_ACTION);
        final List<ResolveInfo> matchedServices = context.getPackageManager().queryIntentServices(intent, 0);

        if(matchedServices.size() == 1) {
            String packageName = info.serviceInfo.packageName;
            String serviceName = info.serviceInfo.name;
            intent.setComponent(new ComponentName(packageName, serviceName));
        }
        return intent;
    }
}

和我的测试班级看起来像这样,

class MyIntentProviderTest {

  @Mock
  private Context mContext;
  @Mock
  private PackageManager mockPackageManager;
  @Mock
  private Intent mockIntent;
  @Mock
  private ResolveInfo resolveInfo;
  private List<ResolveInfo> mockResolvedInfoList;

    @Before
    public void setup() {
        myIntentProvider = new MyIntentProvider();  
        mockResolvedInfoList = new ArrayList<ResolveInfo>();
        mockResolvedInfoList.add(new ResolveInfo());  
    }

    @Test
    public void provideIntent() {

        //setup
        mContext = spy(RuntimeEnvironment.application);
        doReturn(mockResolvedInfoList).when(mockPackageManager).queryIntentServices(any(Intent.class), anyInt());

        //test
        final Intent intent = myIntentProvider.provideBindingIntent(mContext);

        //verify
        assertNotNull(intent.getComponent());
    }
}

但是总是matchedServices的大小返回0。如何模拟呢?

android unit-testing junit mockito robolectric
2个回答
0
投票

我看不到您在列表中添加任何内容,因此它将始终返回0。您有两个选择,要么获取包含一些数据的列表,要么像这样对它进行存根。

doReturn(1).when(mockPackageManager).queryIntentServices(any(Intent.class), anyInt()).size();

然后在正确调用方法后,对您的内容进行验证或声明。


0
投票

我建议修改您的MyIntentProvider类,使其更具可测试性。换句话说,创建一个提供matchedServices的变量,而不是从另一个类获取它。您的课程可能如下所示。

public class MyIntentProvider {

    private List<Service> matchedServices; 
    private Info info;

    public void setInfo(Info info) {
        this.info = info;
    }

    public Info getInfo() {
        return this.info;
    }

    public List<Service> getMatchedServices() {
        return this.matchedServices;
    }

    public void setMatchedServices(List<Service> matchedServices) {
        this.matchedServices = matchedServices; 
    }

    public Intent provideIntent(final Context context) {
        final Intent intent = new Intent();
        intent.setAction(MY_ACTION);
        final List<ResolveInfo> matchedServices = context.getPackageManager().queryIntentServices(intent, 0);

        if(matchedServices != null && matchedServices.size() == 1) {
            String packageName = info.serviceInfo.packageName;
            String serviceName = info.serviceInfo.name;
            intent.setComponent(new ComponentName(packageName, serviceName));
        }
        return intent;
    }
}

一旦您像上面那样设置了类,为该类编写测试就变得更加容易。如果没有必要,您实际上不必模拟实例。

public class MyIntentProviderTest {

    private MyIntentProvider myIntentProvider;
    private Info dummyInfo;
    private List<Service> dummyMatchedServices;

    @Before
    public void setup() {
        myIntentProvider = new MyIntentProvider();  
        dummyInfo = new Info();
        dummyMatchedServices = getDummyMatchedServices(); // Just return a dummy list as per your need

        // Now set it here 
        myIntentProvider.setInfo(dummyInfo);
        myIntentProvider.setMatchedServices(dummyMatchedServices);
    }

    @After
    public void tearDown() {
        myIntentProvider = null;
        dummyInfo = null;
        dummyMatchedServices = null;
    }

    @Test
    public void testHere() {
        // Do the testing here
    }
}

我希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.