我正在使用UI Tests
为我的Android
应用创建Espresso
。
我有一个login
屏幕,其中只包含两个Fields
(用户和密码)和一个Button
。
我正在使用Retrofit
,但我想嘲笑API
回复,因此我创建了RetrofitMockClient
。
例如,在下一个Test
我有意输入错误的password
来检查是否显示了error
消息。
@Test
public void loginFailed() {
onView(withId(R.id.login_user_name)).perform(typeText("myUser"));
onView(withId(R.id.login_user_password)).perform(typeText("wrongPassword"), closeSoftKeyboard());
onView(withId(R.id.login_button)).perform(click());
// Failed login shows error message.
onView(withText(R.string.login_error_message)).check(matches(isDisplayed()));
}
问题在于,当执行点击时,会触发Retrofit
API
来自我想要模拟的电话。
有关它的任何想法?我对UI Test
/ Unit Tests
有点困惑,如果这个Test
有意义。我只想检查error message
在API
过程中error
返回login
时是否显示MockWebServer
。
提前致谢。
修改
我已经使用fzxt
作为用户RestServiceTestHelper
建议使用了class
示例中提供的Test
@RunWith(AndroidJUnit4.class)
public class LoginUIAndroidTest {
private static MockWebServer mockWebServer;
@Rule
public ActivityTestRule<LoginActivity> mActivityRule = new IntentsTestRule<>(LoginActivity.class,
true, // initialTouchMode
false); // launchActivity - false so we could customize the intent
@BeforeClass
public static void startMockServer() throws Exception {
mockWebServer = new MockWebServer();
mockWebServer.start();
mockWebServer.url("/");
}
@AfterClass
public static void shutdownMockServer() throws Exception {
mockWebServer.shutdown();
}
@Test
public void testLoginSuccess() throws Exception {
String fileName = "quote_login_200_ok.json";
mockWebServer.enqueue(new MockResponse()
.setResponseCode(200)
.setBody(RestServiceTestHelper.getStringFromFile(getInstrumentation().getContext(), fileName)));
onView(withId(R.id.login_user_name)).perform(typeText("user"));
onView(withId(R.id.login_user_password)).perform(typeText("password"), closeSoftKeyboard());
onView(withId(R.id.login_button)).perform(click());
// Successful login moves user to next screen.
intended(hasComponent(new ComponentName(getInstrumentation().getTargetContext(), ProjekteActivity.class)));
}
。
现在我的RestServiceTestHelper.java
看起来像这样:
public class RestServiceTestHelper {
public static String convertStreamToString(InputStream is) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
}
public static String getStringFromFile(Context context, String filePath) throws Exception {
final InputStream stream = context.getResources().getAssets().open(filePath);
String ret = convertStreamToString(stream);
//Make sure you close all streams.
stream.close();
return ret;
}
}
LoginActivity
:
public class LoginActivity extends Activity {
...
@OnClick(R.id.login_button)
public void loginUser(final View view) {
final MyRetrofitService service = createRetrofitService();
service.login(new AuthenticationLoginDTO(email, password, deviceUUID), new Callback < AuthenticationDTO > () {
@Override
public void success(final AuthenticationDTO authenticationDTO, final Response response) {}
@Override
public void failure(final RetrofitError retrofitError) {}
});
}
protected MyRetrofitService createRetrofitService() {
final RequestInterceptor requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(final RequestInterceptor.RequestFacade request) {
request.addHeader(getString(R.string.header_api_key), getString(R.string.api_key));
request.addHeader(getString(R.string.header_context), getString(R.string.context));
}
};
final Gson dateTimeConverter = new GsonBuilder()
.registerTypeAdapter(DateTime.class, new DateTimeConverter())
.create();
final RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("/")
.setConverter(new GsonConverter(dateTimeConverter))
.setRequestInterceptor(requestInterceptor)
.setExecutors(AsyncTask.THREAD_POOL_EXECUTOR, new MainThreadExecutor())
.setLogLevel(RestAdapter.LogLevel.FULL).setLog(new AndroidLog(Config.TAG))
.build();
return restAdapter.create(MyRetrofitService.class);
}
}
这是我的Retrofit
:
public interface NGOPService {
String AUTHENTICATION_ENDPOINT = "";
@POST(AUTHENTICATION_ENDPOINT)
void login(@Body AuthenticationLoginDTO authRequest, Callback < AuthenticationDTO > callback);
}
Espresso
界面:
click
我遗漏了某些内容,因为当Api
执行MockWebServer
操作时,正在调用真实onView(withId(R.id.login_button)).perform(click());
而不是Dagger 2
。
Retrofit 2.0
我已经看过使用Retrofit 1.9
和 SELECT drawid,contact,dnd,mem.name, count(*) as numPayments,NULL
numPaidPayments ,NULL PAID_CONTACT,NULL NAME_PAID FROM mem
LEFT JOIN payment ON (mem.drawid = payment.draw) GROUP BY
drawid HAVING numPayments < 4
UNION
SELECT NULL drawid,NULL contact, NULL dnd, NULL name,NULL
numPayments,COUNT(*) as numPaidPayments ,contact PAID_CONTACT,mem.name
NAME_PAID FROM mem
INNER JOIN payment ON (mem.drawid = payment.draw) GROUP BY
drawid HAVING numPaidPayments >= 4
的一些示例,但不幸的是,我现在必须使用flash_messages.htm
。
提前致谢。