Espresso的IdlingResource with Retrofit 2

时间:2017-01-09 00:09:37

标签: android android-fragments automated-tests retrofit2 android-espresso

我是Espresso的新手,并尝试在片段上编写测试,该片段在实例化时进行Retrofit调用。收到调用后,我想检查片段以查看是否存在视图。我正在为片段使用IdlingResource并设置一个要调用的侦听器,在收到响应时将ResourceCallback转换为空闲(遵循此处实现中的一些步骤:https://stackoverflow.com/a/30820189/4102823)。

当用户登录并启动MainActivity时,我的片段会被实例化。问题是我不认为我的IdlingResource设置正确,我不知道它有什么问题。甚至在片段启动并进行调用之后,它甚至都没有被构造,即使我在测试的setUp()方法之前注册了IdlingResource。因此,我认为这里的主要问题是我在运行测试时如何将IdlingResource与片段一起实例化,而不是在它之后。问题可能在@Rule中吗?在测试可以在片段上运行之前,它是否启动MainActivity(创建一个NewsfeedFragment实例)?如果是这样,我将如何使用我的片段的规则?

这是我的片段:

public ProgressListener mProgressListener;
public boolean mIsProgressShown = true;

public interface ProgressListener {
    void onProgressShown();
    void onProgressDismissed();
}

public void setProgressListener(ProgressListener progressListener) {
    mProgressListener = progressListener;
}

public NewsfeedFragment() {
}

public static NewsfeedFragment newInstance() {
    return new NewsfeedFragment();
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    OSUtil.setTranslucentStatusBar(getActivity().getWindow(), this.getContext());
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    mRootView = (SwipeRefreshLayout) inflater.inflate(R.layout.fragment_newsfeed, container, false);
    mNewsfeedFramelayout = (FrameLayout) mRootView.findViewById(R.id.newsfeed_framelayout);
    mProgressView = (ProgressBar) mRootView.findViewById(R.id.newsfeed_progress);
    mPageIndictorView = (FrameLayout) mRootView.findViewById(R.id.page_indicator);
    mPageIndicator = (TextView) mRootView.findViewById(R.id.page_indicator_text);
    mRootView.setOnRefreshListener(this);

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) mRootView.findViewById(R.id.newsfeed_viewpager);
    mPageChangeListener = this;

    if (savedInstanceState != null) {
        mTabPosition = savedInstanceState.getInt(EXTRA_TAB_POSITION);
        mViewPager.setCurrentItem(mTabPosition);
    }

    fetchNewsFeed();

    return mRootView;
}

private void fetchNewsFeed() {
    if (NetworkUtils.isConnectedToInternet(getActivity())) {
        if (NetworkUtils.getService() != null) {
            if (mRootView.isRefreshing()) {
                dismissProgress();
            } else {
                showProgress();
            }
            showProgress();

            Call<Newsfeed> call = NetworkUtils.getService().getNewsfeed();
            call.enqueue(new Callback<Newsfeed>() {
                @Override
                public void onResponse(Call<Newsfeed> call, Response<Newsfeed> response) {
                    if (response.isSuccessful()) {

                        dismissProgress();
                        mNewsfeed = response.body();
                        FragmentManager fragmentManager = getChildFragmentManager();
                        mNewsfeedPagerAdapter = new NewsfeedPagerAdapter(fragmentManager, mNewsfeed.getNewsfeedItems());
}

...


    private void showProgress() {
        // show the progress and notify the listener
        if (mProgressListener != null){
            setProgressIndicatorVisible(true);
            notifyListener(mProgressListener);
        }
    }

    public void dismissProgress() {
        // hide the progress and notify the listener
        if (mProgressListener != null){
            setProgressIndicatorVisible(false);
            mIsProgressShown = false;
            notifyListener(mProgressListener);
        }
    }

    public boolean isInProgress() {
        return mIsProgressShown;
    }

    private void notifyListener(ProgressListener listener) {
        if (listener == null){
            return;
        }
        if (isInProgress()){
            listener.onProgressShown();
        }
        else {
            listener.onProgressDismissed();
        }
    }

这是IdlingResource:

public class ProgressIdlingResource implements IdlingResource, NewsfeedFragment.ProgressListener {

private ResourceCallback mResourceCallback;
private NewsfeedFragment mNewsfeedFragment;


public ProgressIdlingResource(NewsfeedFragment fragment) {
    mNewsfeedFragment = fragment;
    mNewsfeedFragment.setProgressListener(this);
}

@Override
public String getName() {
    return "ProgressIdlingResource";
}

@Override
public boolean isIdleNow() {
    return !mNewsfeedFragment.mIsProgressShown;
}

@Override
public void registerIdleTransitionCallback(ResourceCallback callback) {
    mResourceCallback = callback;
}

@Override
public void onProgressShown() {

}

@Override
public void onProgressDismissed() {
    if (mResourceCallback == null) {
        return;
    }
    //Called when the resource goes from busy to idle.
    mResourceCallback.onTransitionToIdle();
}
}

片段测试:

public class NewsfeedFragmentTest {
@Before
public void setUp() throws Exception {
    Espresso.registerIdlingResources(new ProgressIdlingResource((NewsfeedFragment) MainActivity.getCurrentFragment()));
}

@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);

@Test
public void getViewPager() throws Exception {
    onView(allOf(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE),
            withId(R.id.newsfeed_viewpager))).check(matches(isDisplayed()));
}

@Test
public void getNewsfeedItems() throws Exception {
    onView(withId(R.id.page_indicator)).check(matches(isDisplayed()));
}

}

1 个答案:

答案 0 :(得分:2)

Retrofit正在使用OkHttp,并且有一种标准方法来设置IdlingResource。请参阅OkHttp IdlingResource