New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 636189 link

Starred by 2 users

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 2
Type: Feature



Sign in to add a comment

Add support for mocking without SDK dependency via Mockito

Project Member Reported by changwan@chromium.org, Aug 10 2016

Issue description

We have Java host tests such as JUnit4 and Robolectric, but they are based on
Robolectric and they do not support Android API > 21.

For example, your test cannot import any class that uses 21 or higher as shown in this code:
https://codereview.chromium.org/1721613002/

In Android, MockitoJUnitRunner seems to do this:
https://developer.android.com/training/testing/unit-testing/local-unit-tests.html

This seems to be a device-driven test type, so I'm curious if we are able to support this as well.

(How should we configure / divide host-driven and device-driven tests?)

 
Blockedon: 522043
Cc: jbudorick@chromium.org
Components: -Test Test>Android
Owner: ----
Status: Available (was: Unconfirmed)
You might be interested in https://codereview.chromium.org/2195143002/
WRT your second question: what do you mean "host-driven" and "device-driven" tests? Tests that run on the host vs tests that run on the device?
Re #2, that's correct.

Robolectric and host tests does not support SDK > 21, does it? Sdk 21 is L so it's quite outdated.
It looks like https://github.com/robolectric/robolectric/releases/tag/robolectric-3.1 adds support for 22 and 23. We haven't looked at it yet because the switch from 2.4 -> 3.0 has been challenging enough (and because 3.1 only came out in June).
Blockedon: -522043
That's exactly why I'm asking it. The benefits of using Robolectric (or JUnit4 based on Robolectric) are, as I understand,
1) Speed of test execution
2) Easy control of context and other Android elements

However, with the incremental build 1) is not as much as before.
So far I haven't found a case where 2) is a real benefit.

One big problem with Robolectric is that it is painful to follow up with Android versions (and sometimes not available at all).

We need to mock away external components to add unit tests for structurally complicate classes, and device-driven mockito junit runner seems to be a good alternative. At least this seems to be the Android's official way of mockito support.

In this sense, let me remove the dependency on Robolectric 3.0.

Cc: -jbudorick@chromium.org
Owner: jbudorick@chromium.org
Status: Started (was: Available)
Ah, ok. I think I understand what you mean.

I think it's already possible to do this, though there are no tests in Chromium that do so. I'm not sure, though, so let me experiment a little bit and get back to you.
er, actually, before I do, I want to clarify:

> We need to mock away external components to add unit tests for structurally complicate classes, and device-driven mockito junit runner seems to be a good alternative. At least this seems to be the Android's official way of mockito support.

I think their page is advocating for using mockito on the host, not the device:

"""
If your unit test has no dependencies or only has simple dependencies on Android, you should run your test on a local development machine. This testing approach is efficient because it helps you avoid the overhead of loading the target app and unit test code onto a physical device or emulator every time your test is run.
"""


I'm going to experiment w/ a host-side use of mockito; I think a device-side use would (1) be blocked other tasks and (2) not save much over a non-mocking instrumentation test.
Sounds good. Thanks!
Cc: jbudorick@chromium.org
Labels: Type-Feature
Owner: ----
Status: Available (was: Started)
Summary: Add support for mocking parts of the Android SDK via Mockito (was: Need to support MockitoJUnitRunner)
I looked at this some, and unfortunately the answer is a bit less clear than I initially thought. We can already use mockito (and MockitoJUnitRunner) to mock things _not_ in the Android SDK. (I think we can also mock things at the API levels that Robolectric provides, but that's not particularly useful.)

Mocking APIs from the SDK versions we're building against normally will require building differently. Our junit/robolectric suites currently build against the robolectric versions of the android jar, which has real implementations but only supports up to sdk level 18 (robolectric 2.4) / 21 (3.0) / 23 (3.1). Tests that want to mock newer Android code would have to build against the normal android jar, which has stub implementations of everything. I'm not sure we could have both tests that use robolectric and tests that use mockito+new android apis in the same suite; that'd be a question for further investigation.

We're definitely not doing this in Q3, but we'll consider doing so afterward.
Summary: Add support for mocking without SDK dependency via Mockito (was: Add support for mocking parts of the Android SDK via Mockito)
What I tried was not to mock out SDK APIs, but just importing classes that reference the new SDK caused an error. Changing the summary accordingly.
Owner: mikec...@chromium.org
So what you want is to use Mockito for SDK APIs in Junit tests? If so, I can look into this. I think I have a good idea of what needs to be changed.
Cc: yabinh@chromium.org
Hmm... Actually when I tried last time, I didn't have a failing case:

https://codereview.chromium.org/1721613002

I suspect that this has to with our decision to base ThreadedInputConnection off BaseInputConnection instead of InputConnection. But that decision may change in the future and if that happens newly added InputConnection APIs may not work well.

In this sense, I'm still concerned that Robolectrics may not catch up on Android SDK versions in the future. Is there any way to run mockito tests without Robolectrics dependency?

Realistically we will keep deriving from BaseInputConnection forever.  It will never be worth it to take the risk of breaking WebView apps for the sake of some minor class hierarchy cleanup.  Does that make your concern moot?
Android seems to provide a special android.jar with non-final classes that lets you mock them out with Mockito.

I think what we would have to do is something like...

- rename junit_binary GN target to robolectric_binary. This would include the Robolectric DEPS and the Robolectric android sdk jar.

- change junit_binary target to depend on the special android.jar made for mocking and Mockito.

I think this is the simplest way to do this.
Project Member

Comment 15 by sheriffbot@chromium.org, Sep 22 2017

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue.

Sorry for the inconvenience if the bug really should have been left as Available. If you change it back, also remove the "Hotlist-Recharge-Cold" label.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Cc: -jbudorick@chromium.org ctzsm@chromium.org yolandyan@chromium.org
Owner: jbudorick@chromium.org
jbudorick@, could you triage this one?

We're still running into this problem. We had to work around this for TextClassifier API.
Status: Assigned (was: Untriaged)

Sign in to add a comment