简体   繁体   中英

How to mock a custom ImageView for activity unit testing

I have a LoginActivity which loads a SplashFragment in onResume() .

The layout XML of the splash fragment contains a custom ImageView called RotatingImageView which, as the name suggests, starts rotating a source image as soon as it's attached to the Window.

Now this is causing problems when I try to write a unit test for LoginActivity using ActivityInstrumentationTestCase2<LoginActivity> . I'm trying to run the tests on a real device(unrooted), not an emulator.

The getActivity() call starts the activity but because of the rotating image view (which is an animation btw), the espresso is stuck. I know that espresso doesn't like an animation going on there. I get exceptions that

"espresso couldn't launch intent within 45 seconds. Perhaps the main thread has not gone idle within a reasonable amount of time? There could be an animation or something constantly repainting the screen. Or the activity is doing network calls on creation? See the thread dump logs. For your reference the last time the event queue was idle before your activity launch request was 1487296262885 and now the last time the queue went idle was: 1487296262885. If these numbers are the same your activity might be hogging the event queue..."

Now obviously the problem is to somehow stop/mock the animation.

  1. I have already disabled all animation options from Device -> Settings -> Developer Options but still when activity is launched I see the image spinning so this doesn't help.

  2. I've also looked into Disable animations for Espresso tests but this hasn't helped me much either. I could have been doing it wrong but anyways, it's not helping.

  3. Another option is to launch LoginActivity using a special intent which tells the activity that this is launching under test so when you load the fragment it disables the animation. This method works but it's not ideal because it involves adding code in the main class which is purely for testing.

One other solution could be to mock RotatingImageView and inject it into SplashFragment before it starts loading. I would have mocked out the call to startSpinningAnimation so when it's loaded into the Window it won't start the animation.

My question is: Is it possible? Can I mock and inject this custom imageView into my fragment somehow, before the call to getActivity() is done?

Yes, it is possible, you can create a class called AnimationUtil , put your animation methods in that class and mock them during test.

public Animation getWhateverAnimation(int duration){
    RotateAnimation anim = new RotateAnimation(0f, 350f, 15f, 15f);
    anim.setInterpolator(new LinearInterpolator());
    anim.setRepeatCount(Animation.INFINITE);
    anim.setDuration(duration);
    return anim;
}

and create a MockAnimationUtil that extend AnimationUtil in your androidTest package(not main package) and override and method.

public Animation getWhateverAnimation(int duration){
    return super.getWhateverAnimation(0);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM