针对retrofit2的Android JUnit测试给出了空指针异常



我已经用Mokito为我的应用程序实现了Junit测试。我喜欢测试登录活动。但正在获取Nullpointer异常。

登录活动

package com.example.activity;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.view.Gravity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.example.R;
import com.example.api.APIClient;
import com.example.api.APIInterFace;
import com.example.api.apipojo.ChatListDataFinal;
import com.example.api.apipojo.GetCustomerIDResponse;
import com.example.api.apipojo.LoginRequest;
import com.example.api.apipojo.LoginSuccessRes;
import com.example.base.BaseActivity;
import com.example.customViews.CustomEditText;
import com.example.customViews.CustomTextView;
import com.example.helpers.PreferencesManager;
import com.example.utils.Constants;
import com.example.utils.Log;
import com.example.utils.Utils;
import com.google.gson.Gson;
import org.json.JSONObject;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class LoginActivity extends BaseActivity {
private CustomEditText emailEditText, passwordEditText;
private FrameLayout progressBarLayout;
private CheckBox checkBox;
CustomTextView rememberTextView;
//   List<LoginSuccessRes.TenantUnit> tenantUnits;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
initializeViews();
}
@Override
public void onBackPressed() {
closeTheApp();
}
private void closeTheApp() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
try {
finishAffinity();
finish();
} catch (Exception e) {
e.printStackTrace();
}
this.overridePendingTransition(R.anim.enter, R.anim.exit);
}
public void getCustomerId(String email, final String pass) {

showProgress(progressBarLayout);
//  Log.e("apiInterFace >>",apiInterFace.toString());
if (apiInterFace == null) {
apiInterFace = APIClient.getAPIClient().create(APIInterFace.class);
}
Call<GetCustomerIDResponse> getCustomerIDResponseCall = apiInterFace.getCustomerId(email);
final String finalEmail = email;
getCustomerIDResponseCall.enqueue(new Callback<GetCustomerIDResponse>() {
@Override
public void onResponse(Call<GetCustomerIDResponse> call, Response<GetCustomerIDResponse> response) {
try {
ChatListDataFinal chatListDataFinal = null;
int resCode = response.raw().code();
hideProgress(progressBarLayout);
if ((resCode == 200) || (resCode == 201) || (resCode == 204)) {
GetCustomerIDResponse obj = response.body();
if (obj != null) {
if (obj.getSuccess()) {
if (obj.getData().toString().equalsIgnoreCase("[]")) {
} else {
String customerId = obj.getData().get(0).toString();
Log.e("customerId >>", customerId);
prefManager.setStringValue(PreferencesManager.CUSTOMER_ID, customerId);
loginToServer(finalEmail, pass, customerId);
}

}

}
} else {
assert response.errorBody() != null;
JSONObject msgObj = new JSONObject(response.errorBody().string());
utilsErrorResHandle(LoginActivity.this, msgObj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<GetCustomerIDResponse> call, Throwable t) {
Log.e("inside failure >>", t.getCause().toString());
hideProgress(progressBarLayout);
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.loginTextView:
loginRequest();
break;
case R.id.rememberTextView:
// checkBox.performClick();
showTermsPopup();
break;
case R.id.forgotPassTextView:
Intent forgotPasswordIntent = new Intent(LoginActivity.this, ForgotPasswordActivity.class);
startActivity(forgotPasswordIntent);
break;
}
}
public void showTermsPopup() {
final View popupView = LoginActivity.this.getLayoutInflater().inflate(R.layout.terms_and_conditions_layout, null);
final PopupWindow popupWindow = new PopupWindow(popupView,
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
RelativeLayout layPopup = (RelativeLayout) popupView.findViewById(R.id.layPopup);
LinearLayout layTerms = (LinearLayout) popupView.findViewById(R.id.layTerms);
CustomTextView closeTextView = (CustomTextView) popupView.findViewById(R.id.closeTextView);
CustomTextView termsTextView = (CustomTextView) popupView.findViewById(R.id.termsTextView);
CustomTextView termsTitleView = (CustomTextView) popupView.findViewById(R.id.termsTitleTextView);
termsTextView.setText(Constants.TERMS);
closeTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popupWindow.dismiss();
}
});
layPopup.setPadding(0, widthSpace * 6, 0, 0);
/*RelativeLayout.LayoutParams cntParentLayoutParams = (RelativeLayout.LayoutParams) layPopup.getLayoutParams();
cntParentLayoutParams.setMargins(widthSpace * 6, widthSpace * 6, widthSpace * 6, widthSpace * 6);
layPopup.setLayoutParams(cntParentLayoutParams);*/
RelativeLayout.LayoutParams termsLayoutParams = (RelativeLayout.LayoutParams) layTerms.getLayoutParams();
termsLayoutParams.setMargins(widthSpace * 4, widthSpace * 4, widthSpace * 4, widthSpace * 4);
layTerms.setLayoutParams(termsLayoutParams);
LinearLayout.LayoutParams termsTitleViewLayoutParams = (LinearLayout.LayoutParams) termsTitleView.getLayoutParams();
termsTitleViewLayoutParams.setMargins(widthSpace * 2, widthSpace * 2, widthSpace * 6, widthSpace * 2);
termsTitleView.setPadding(widthSpace * 2, widthSpace * 2, widthSpace * 2, widthSpace * 2);
termsTitleView.setLayoutParams(termsTitleViewLayoutParams);
FrameLayout.LayoutParams termsTextViewLayoutParams = (FrameLayout.LayoutParams) termsTextView.getLayoutParams();
termsTextViewLayoutParams.setMargins(widthSpace * 2, 0, widthSpace * 2, widthSpace * 2);
termsTextView.setPadding(widthSpace * 2, widthSpace * 2, widthSpace * 2, widthSpace * 2);
termsTextView.setLayoutParams(termsTextViewLayoutParams);
RelativeLayout.LayoutParams closeImageViewParams = (RelativeLayout.LayoutParams) closeTextView.getLayoutParams();
closeImageViewParams.setMargins(widthSpace * 2, widthSpace * 2, widthSpace * 4, widthSpace * 2);
closeImageViewParams.height = widthSpace * 4;
closeImageViewParams.width = widthSpace * 4;
closeTextView.setLayoutParams(closeImageViewParams);
// If the PopupWindow should be focusable
popupWindow.setFocusable(true);
popupWindow.setTouchable(true);
// If you need the PopupWindow to dismiss when when touched outside
popupWindow.setBackgroundDrawable(new ColorDrawable());
popupWindow.setAnimationStyle(R.style.Animation);
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
}

public void initializeViews() {
LinearLayout cntParentLayout = findViewById(R.id.cntParentLayout);
ImageView logoImageView = findViewById(R.id.logoImageView);
emailEditText = findViewById(R.id.emailEditText);
passwordEditText = findViewById(R.id.passwordEditText);
CustomTextView loginTextView = findViewById(R.id.loginTextView);
checkBox = findViewById(R.id.checkBox);
rememberTextView = findViewById(R.id.rememberTextView);
String firstWord = "I accept";
String lastWord = " Terms and Conditions";
Spannable spannable = new SpannableString(firstWord + lastWord);
spannable.setSpan(new ForegroundColorSpan(ContextCompat.getColor(LoginActivity.this, R.color.black_color)), 0, firstWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ForegroundColorSpan(ContextCompat.getColor(LoginActivity.this, R.color.colorPrimary)), firstWord.length(), firstWord.length() + lastWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
rememberTextView.setText(spannable);
CustomTextView forgotPassTextView = findViewById(R.id.forgotPassTextView);
progressBarLayout = findViewById(R.id.progressBarLayout);
RelativeLayout.LayoutParams cntParentLayoutParams = (RelativeLayout.LayoutParams) cntParentLayout.getLayoutParams();
cntParentLayoutParams.setMargins(widthSpace * 6, widthSpace * 10, widthSpace * 6, widthSpace * 2);
cntParentLayout.setLayoutParams(cntParentLayoutParams);
LinearLayout.LayoutParams emailEditTextParams = (LinearLayout.LayoutParams) emailEditText.getLayoutParams();
emailEditTextParams.setMargins(0, widthSpace * 6, 0, widthSpace * 2);
emailEditText.setPadding(widthSpace * 2, widthSpace * 2, widthSpace * 2, widthSpace * 2);
emailEditText.setLayoutParams(emailEditTextParams);
LinearLayout.LayoutParams passwordEditTextParams = (LinearLayout.LayoutParams) passwordEditText.getLayoutParams();
passwordEditTextParams.setMargins(0, widthSpace * 4, 0, widthSpace * 2);
passwordEditText.setPadding(widthSpace * 2, widthSpace * 2, widthSpace * 2, widthSpace * 2);
passwordEditText.setLayoutParams(passwordEditTextParams);
LinearLayout.LayoutParams loginTextViewParams = (LinearLayout.LayoutParams) loginTextView.getLayoutParams();
loginTextViewParams.setMargins(widthSpace * 4, widthSpace * 6, widthSpace * 4, widthSpace * 2);
loginTextView.setPadding(widthSpace * 2, widthSpace * 2, widthSpace * 2, widthSpace * 2);
loginTextView.setLayoutParams(loginTextViewParams);
LinearLayout.LayoutParams checkBoxParams = (LinearLayout.LayoutParams) checkBox.getLayoutParams();
checkBoxParams.setMargins(0, widthSpace * 4, widthSpace * 2, widthSpace * 4);
checkBoxParams.height = widthSpace * 5;
checkBoxParams.width = widthSpace * 5;
checkBox.setLayoutParams(checkBoxParams);
RelativeLayout.LayoutParams logoImageViewParams = (RelativeLayout.LayoutParams) logoImageView.getLayoutParams();
logoImageViewParams.setMargins(widthSpace * 6, widthSpace * 4, widthSpace * 6, widthSpace * 6);
logoImageViewParams.height = widthSpace * 8;
logoImageView.setLayoutParams(logoImageViewParams);
forgotPassTextView.setPadding(widthSpace * 2, 0, widthSpace * 2, widthSpace * 6);
loginTextView.setOnClickListener(this);
rememberTextView.setOnClickListener(this);
forgotPassTextView.setOnClickListener(this);
}
private void loginRequest() {
String email = Objects.requireNonNull(emailEditText.getText()).toString().trim();
String pass = Objects.requireNonNull(passwordEditText.getText()).toString().trim();
email = email.toLowerCase();
if (!Utils.isNetWorkAvailable(this)) {
showMessage(this, this.getResources().getString(R.string.no_internet));
} else if (TextUtils.isEmpty(email)) {
showMessage(this, this.getResources().getString(R.string.please_enter_email));
} else if (!Utils.isEmailValid(email)) {
showMessage(this, this.getResources().getString(R.string.please_enter_valid_email));
} else if (TextUtils.isEmpty(pass)) {
showMessage(this, this.getResources().getString(R.string.please_enter_pass));
} else if (!checkBox.isChecked()) {
showMessage(this, this.getResources().getString(R.string.please_accept_terms));
} else {
if (Utils.isNetWorkAvailable(this)) {
showProgress(progressBarLayout);
getCustomerId(email, pass);

} else {
showMessage(this, this.getResources().getString(R.string.no_internet));
}
}
}
public void loginToServer(String email, String pass, String custId) {
LoginRequest loginReq = new LoginRequest();
loginReq.setUsername(email);
loginReq.setPassword(pass);
Call<LoginSuccessRes> loginCall = apiInterFace.requestLogin(Constants.PLATFORM, loginReq, custId);
loginCall.enqueue(new Callback<LoginSuccessRes>() {
@Override
public void onResponse(Call<LoginSuccessRes> call, Response<LoginSuccessRes> response) {
try {
int resCode = response.raw().code();
if ((resCode == 200) || (resCode == 201) || (resCode == 204)) {
if (response.body().getData().getUserRole().equalsIgnoreCase("tenant")) {
int userId = response.body().getData().getUser().getId();
String userToken = response.body().getData().getToken();
prefManager.setIntValue(PreferencesManager.LOGIN_USER_ID, userId);
prefManager.setStringValue(PreferencesManager.LOGIN_USER_TOKEN, userToken);
//  prefManager.setStringValue(PreferencesManager.LOGIN_USER_PROFILE_IMAGE, response.body().getData().getUser().getProfile_pic());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_ROLE, response.body().getData().getUserRole());
String email = response.body().getData().getUser().getUser().getEmail();
prefManager.setStringValue(PreferencesManager.LOGIN_USER_EMAIL, email);
prefManager.setStringValue(PreferencesManager.LOGIN_USER_TYPE, response.body().getData().getUser().getType());
// prefManager.setStringValue(PreferencesManager.LOGIN_USER_ROLE_TYPE, response.body().getData().getUser().getRole_type());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_ADDRESS, response.body().getData().getUser().getAddress().get(0).getAddress().getAddress1());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_ADDRESS_TYPE, response.body().getData().getUser().getAddress().get(0).getAddress().getAddressType());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_PROFILE_CITY, response.body().getData().getUser().getAddress().get(0).getAddress().getCity());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_STATE, response.body().getData().getUser().getAddress().get(0).getAddress().getState());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_COUNTRY, response.body().getData().getUser().getAddress().get(0).getAddress().getCountryCode());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_PROFILE_ZIPCODE, response.body().getData().getUser().getAddress().get(0).getAddress().getZipcode());
String fName = response.body().getData().getUser().getUser().getFirstName();
String lName = response.body().getData().getUser().getUser().getLastName();
String mobile = response.body().getData().getUser().getUser().getMobileNumber();
prefManager.setStringValue(PreferencesManager.LOGIN_USER_PROFILE_F_NAME, fName);
prefManager.setStringValue(PreferencesManager.LOGIN_USER_PROFILE_L_NAME, lName);
prefManager.setStringValue(PreferencesManager.LOGIN_USER_MOBILE, mobile);
// prefManager.setStringValue(PreferencesManager.LOGIN_USER_COI_FILE, response.body().getData().getUser().getCoi_file());
//  prefManager.setStringValue(PreferencesManager.LOGIN_USER_COI_FILE_EXPIRY, response.body().getData().getUser().getUser().getCoi_expiry_date());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_PROFILE_UNIQUE_NAME, response.body().getData().getUser().getUser().getRoleName());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_PROFILE_RECOVERY_EMAIL, response.body().getData().getUser().getUser().getRecoveryEmail());
prefManager.setStringValue(PreferencesManager.LOGIN_USER_PROFILE_ROLE_NAME, response.body().getData().getUser().getUser().getRoleName());
prefManager.setBooleanValue(PreferencesManager.LOGIN_USER_ACTIVE, response.body().getData().getUser().getIsActivated());
String tenantUnits = response.body().getData().getUser().getTotalUnits();
String total_square_feet = response.body().getData().getUser().getTotalSquareFeet();
prefManager.setStringValue(PreferencesManager.TENANT_UNIT, tenantUnits);
Gson gson = new Gson();
String loginResponse = gson.toJson(response.body());
prefManager.setStringValue(PreferencesManager.LOGIN_RESPONSE, loginResponse);
Intent dashBoardIntent = new Intent(LoginActivity.this, TutorialActivity.class);
dashBoardIntent.putExtra("isFromLogin", true);
dashBoardIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
dashBoardIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(dashBoardIntent);
finish();
}

} else {
assert response.errorBody() != null;
JSONObject msgObj = new JSONObject(response.errorBody().string());
utilsErrorResHandle(LoginActivity.this, msgObj);
}
hideProgress(progressBarLayout);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<LoginSuccessRes> call, Throwable t) {
Log.e("inside failure>>", t.getMessage());
hideProgress(progressBarLayout);
}
});
}
}

测试活动

public class LoginActivityTest1 {
String email="qa04tenantttt@mailinator.com", password="12345678",custID="qa2";
@Mock
APIInterFace apiInterFace;
@InjectMocks
LoginActivity loginActivity;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}

@Test
public void testOnBackPressed() throws Exception {
loginActivity.onBackPressed();
}
@Test
public void testGetCustomerId() throws Exception {
when(apiInterFace.requestLogin(anyString(), any(), anyString())).thenReturn(null);
when(apiInterFace.getCustomerId(anyString())).thenReturn(null);
loginActivity.getCustomerId(email, password);
}
@Test
public void testLoginToServer() throws Exception {
when(apiInterFace.requestLogin(anyString(), any(), anyString())).thenReturn(null);
loginActivity.loginToServer(email, password, custID);
}

@Test
public void testCreateFolder() throws Exception {
LoginActivity.createFolder();
}
@Test
public void testShowProgress() throws Exception {
LoginActivity.showProgress(null);
}
@Test
public void testHideProgress() throws Exception {
LoginActivity.hideProgress(null);
}
}

错误

java.lang.NullPointerException
at com.fyxttenant.activity.LoginActivity.loginToServer(LoginActivity.java:298)
at com.fyxttenant.activity.LoginActivityTest1.testLoginToServer(LoginActivityTest1.java:66)

java.lang.NullPointerException
at com.fyxttenant.activity.LoginActivity.getCustomerId(LoginActivity.java:92)
at com.fyxttenant.activity.LoginActivityTest1.testGetCustomerId(LoginActivityTest1.java:53)

Edit1:改装调用为空,而我运行测试类。

编辑2 APIClient.java:

public class APIClient {
private static final String BASE_URL = "https://example.io/"; 
private static Retrofit retrofit = null;
public static Retrofit getAPIClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(300, TimeUnit.SECONDS)
.build();
if (retrofit == null) {
Gson gson = new GsonBuilder()
.setLenient()
.create();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(okHttpClient)
.build();
}
return retrofit;
}
}

基本活动

public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener {
public int height = 0, width = 0,widthSpace = 0;
public static LayoutInflater mInflater = null;
protected PreferencesManager prefManager = null;
public APIInterFace apiInterFace = null;
public static double selectedLocationLatitude = 0,selectedLocationLongitude = 0;
public static String selectedAddress = "",selectedCity = "", selectedCountry = "";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeConstants();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStop() {
super.onStop();
}
private void initializeConstants() {
Point screenSizePoints = Utils.getDeviceDynamicPixelSize(this);
height = screenSizePoints.y;
width = screenSizePoints.x;
mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
widthSpace = (int)(width * 0.015);
if (prefManager == null) {
prefManager = PreferencesManager.getInstance(this);
}
if (apiInterFace == null) {
apiInterFace = APIClient.getAPIClient().create(APIInterFace.class);
}
}
public static void createFolder(){
File file = new File(Environment.getExternalStorageDirectory(), "test");
if(!file.exists()){
file.mkdir();
}
}
public static void showProgress(FrameLayout layout) {
if(layout != null) {
layout.setVisibility(View.VISIBLE);
}
}
public static void hideProgress(FrameLayout layout) {
if(layout != null) {
layout.setVisibility(View.GONE);
}
}
@Override
protected void onPause() {
super.onPause();
}
}

在单元测试中,您正在调用apiInterFace.requestLogin以返回null:

when(apiInterFace.requestLogin(anyString(), any(), anyString())).thenReturn(null);

LoginActivity.loginToServer中,apiInterFace.requestLogin被调用,其返回用于调用enqueue函数:

Call<LoginSuccessRes> loginCall = apiInterFace.requestLogin(Constants.PLATFORM, loginReq, custId);
loginCall.enqueue(new Callback<LoginSuccessRes>() { ... }

因此,当尝试在loginCall变量中的Call<LoginSuccessRes>的空实例上调用enqueue函数时,您将得到一个NullPointerException

最新更新