android-espresso


Espresso Test Failed: Wanted to match 1 intents. Actually matched 0 intents


I am trying to test that my SplashActivity correctly launches HomeActivity if the user is logged in.
I have looked at related questions on StackOverflow, this seems to be a common issue, but I just cannot seem to get anything to work.
I have watched the test execute on my device and visually verified that SplashActivity is indeed launching HomeActivity.
HomeActivity expects a plain intent with no data.
Here is the full error:
IntentMatcher: has component: has component with: class name: is "com.shoeboxed.fetch.presentation.ui.activities.HomeActivity" package name: an instance of java.lang.String short class name: an instance of java.lang.String
Initial Attempt:
public class SplashActivityTest extends EspressoIntegrationTest {
#Mock
UserRepository userRepository;
#Rule
public IntentsTestRule<SplashActivity> activityRule = new IntentsTestRule<>(SplashActivity.class, true, false);
#Test
public void loggedInUser() {
User user = Fakes.user();
when(userRepository.getUser()).thenReturn(user);
doNothing().when(userRepository).refreshTeam();
activityRule.launchActivity(new Intent());
intended(hasComponent(HomeActivity.class.getName()));
verify(userRepository, times(1)).getUser();
verify(userRepository, times(1)).refreshTeam();
}
}
Second Attempt:
(Trying different matching syntax)
public class SplashActivityTest extends EspressoIntegrationTest {
#Mock
UserRepository userRepository;
#Rule
public IntentsTestRule<SplashActivity> activityRule = new IntentsTestRule<>(SplashActivity.class, true, false);
#Test
public void loggedInUser() {
User user = Fakes.user();
when(userRepository.getUser()).thenReturn(user);
doNothing().when(userRepository).refreshTeam();
activityRule.launchActivity(new Intent());
intended(hasComponent(new ComponentName(getTargetContext(), HomeActivity.class)));
verify(userRepository, times(1)).getUser();
verify(userRepository, times(1)).refreshTeam();
}
}
Third Attempt
(Adding an Idling Resource on the destination activity)
public class SplashActivityTest extends EspressoIntegrationTest {
#Mock
UserRepository userRepository;
#Rule
public IntentsTestRule<SplashActivity> activityRule = new IntentsTestRule<>(SplashActivity.class, true, false);
#Test
public void loggedInUser() {
User user = Fakes.user();
when(userRepository.getUser()).thenReturn(user);
doNothing().when(userRepository).refreshTeam();
WaitActivityIsResumedIdlingResource resource = new WaitActivityIsResumedIdlingResource(HomeActivity.class.getName());
Espresso.registerIdlingResources(resource);
activityRule.launchActivity(new Intent());
intended(hasComponent(new ComponentName(getTargetContext(), HomeActivity.class)));
verify(userRepository, times(1)).getUser();
verify(userRepository, times(1)).refreshTeam();
Espresso.unregisterIdlingResources(resource);
}
private static class WaitActivityIsResumedIdlingResource implements IdlingResource {
private final ActivityLifecycleMonitor instance;
private final String activityToWaitClassName;
private volatile ResourceCallback resourceCallback;
boolean resumed = false;
public WaitActivityIsResumedIdlingResource(String activityToWaitClassName) {
instance = ActivityLifecycleMonitorRegistry.getInstance();
this.activityToWaitClassName = activityToWaitClassName;
}
#Override
public String getName() {
return this.getClass().getName();
}
#Override
public boolean isIdleNow() {
resumed = isActivityLaunched();
if(resumed && resourceCallback != null) {
resourceCallback.onTransitionToIdle();
}
return resumed;
}
private boolean isActivityLaunched() {
Collection<Activity> activitiesInStage = instance.getActivitiesInStage(Stage.RESUMED);
for (Activity activity : activitiesInStage) {
if(activity.getClass().getName().equals(activityToWaitClassName)){
return true;
}
}
return false;
}
#Override
public void registerIdleTransitionCallback(IdlingResource.ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}
}
Here is my base test. It registers an idling resource on my background processes (clean architecture use cases):
public class EspressoIntegrationTest {
private static IdlingResource idlingThreadPool;
private AppComponent oldComponent = app().appComponent();
#Rule
public DaggerMockRule<AppComponent> daggerRule = new DaggerMockRule<>(AppComponent.class, new AppModule(app()))
.set(component -> {
oldComponent = app().appComponent();
app().setAppComponent(component);
});
#BeforeClass
public static void registerResources() {
idlingThreadPool = getIdlingThreadExecutor();
Espresso.registerIdlingResources(idlingThreadPool);
}
#AfterClass
public static void deregister() {
Espresso.unregisterIdlingResources(idlingThreadPool);
}
#After
public void resetApp() {
app().setAppComponent(oldComponent);
}
private static IdlingResource getIdlingThreadExecutor() {
return (IdlingResource) jobExecutor().getThreadPoolExecutor();
}
private static JobExecutor jobExecutor() {
return ((JobExecutor) app().appComponent().threadExecutor());
}
private static App app() {
return (App) getInstrumentation().getTargetContext().getApplicationContext();
}
}
Asserts that the given matcher matches one and only one intent sent by the application under test. This is an equivalent of verify(mock, times(1)) in Mockito. Verification does not have to occur in the same order as the intents were sent. Intents are recorded from the time that Intents.init is called
See documentation
When you use IntentsTestRule Intents.init() will complated after activity created. As far as I understand, you starting HomeActivity in SplashActivity.onCreate and finish SplashActivity.
So you can use ActivityTestRule and call Intents.init() before launching activity, like this:
public class SplashActivityTest extends EspressoIntegrationTest {
#Mock
UserRepository userRepository;
#Rule
public ActivityTestRule<SplashActivity> activityRule = new ActivityTestRule<>(SplashActivity.class, true, false);
#Before
public void setUp() throws Exception{
Intents.init();
}
#Test
public void loggedInUser() {
User user = Fakes.user();
when(userRepository.getUser()).thenReturn(user);
doNothing().when(userRepository).refreshTeam();
activityRule.launchActivity(new Intent());
intended(hasComponent(HomeActivity.class.getName()));
verify(userRepository, times(1)).getUser();
verify(userRepository, times(1)).refreshTeam();
}
#After
public void tearDown() throws Exception{
Intents.release();
}
}

Related Links

Mock server requests Android Espresso UI Testing
Espresso mockWebServer response does not intercept http calls
Android Instrumentation pull test results/files from device
Espresso hangs the UI and the System kills the application
Espresso test with phone asleep
Unable to run espresso test
How to force Espresso wait for Eventbus posts?
Espresso Web + Chrome cust tab
Espresso 2 - How to Test Multiple Activities?
Android Espresso test to check syncness between ViewPager's fragments and TabViews
Is there a way to automate API calls using Espresso?
Android Espresso - Single list with same items (AmbiguousViewMatcherException)
Do Matchers extending hamcrest.BaseMatcher have to be consistent
testing http connection on google cloud test lab devices
Espresso Test Recorder has detached from the device VM
Espresso - Using google espresso how to send email from Gmail app

Categories

HOME
visual-studio
list
windows-8.1
focus
barcode-scanner
exchange-server
enums
antd
kivy
liferay-7
navigation
share
repair
sympy
kurento
phpstorm-2017.1
smooks
jquery-select2-4
trace32
cpu-usage
pyopencl
managed-c++
tortoisemerge
window-managers
webviewclient
offline-caching
running-object-table
sendmessage
guice
premake
quick-nimble
sca
om-next
amazon-kms
cups
cordys-opentext
forms-authentication
android-alarms
task-parallel-library
resampling
ejml
flipkart
fiware-wirecloud
daz3d
freshdesk
email-forwarding
gmaps.js
zend-server
mpmovieplayercontroller
allegro
qtextedit
cocoa-bindings
ipywidgets
xmlbeans
gcloud-node
msbuild-4.0
dpkg
wolfram-language
static-methods
noclassdeffounderror
node-glob
adjacency-list
jeasyui
mathnet
gridbaglayout
gravatar
vimperator
currency-exchange-rates
diawi
decidable
calcite
blank-line
android-studio-import
green-threads
swagger-maven-plugin
wicked-gem
jolie
comctl32
vs-unit-testing-framework
xml-signature
android-2.3-gingerbread
fileshare
ivalueconverter
ctp
jmenubar
apache-shindig
statechart
unicoins
ntlmv2
user-forums
multiscaleimage
telerik-ajax
uitextfielddelegate
trialware
n-queens
memory-pool
sigar
glx
motodev-studio
qt-mobility
gaelyk
android-2.1-eclair
principles
facebook-fbml
chronic

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App