Как макетировать (или) тестировать переменную уровня метода в Android? - PullRequest
1 голос
/ 23 декабря 2019

У меня есть что-то вроде этого,

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. Какиздеваться над этим?

1 Ответ

0 голосов
/ 28 декабря 2019

Я бы предложил изменить класс 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
    }
}

Надеюсь, это поможет.

...