问题描述:

I do have to two fragments in my app. I want to test all views in each one of them.

So here is my code for the first fragment.

@RunWith(RobolectricGradleTestRunner.class)

@Config(constants = BuildConfig.class,sdk = 21)

public class LoginFragmentTest {

MainActivity activity;

Button loginButton;

Welcome welcomeActivity;

@Before

public void setUp() throws Exception {

activity = Robolectric.setupActivity(MainActivity.class);

loginButton = getButton(activity,R.id.loginButton);

}

@Test

public void loginFragmentShouldNotBeNull(){

LoginFragment loginFragment = new LoginFragment();

startFragment(loginFragment, AppCompatActivity.class);

assertNotNull(loginFragment);

}

@Test

public void shouldHaveUserNameEntry() throws Exception{

EditText nameEntry = getEditText(activity,R.id.user_name);

assertViewIsVisible(nameEntry);

}

@Test

public void shouldHavePasswordEntry() throws Exception

{

EditText passEntry = getEditText(activity,R.id.user_pass);

assertViewIsVisible(passEntry);

}

@Test

public void shouldHaveLoginButton() throws Exception{

assertNotNull(loginButton);

assertViewIsVisible(loginButton);

}

@Test

public void shouldStartNewActivityWhenLoginButtonClicked() throws Exception

{

loginButton.performClick();

Intent intent = new Intent(Intent.ACTION_VIEW);

welcomeActivity = Robolectric.buildActivity(Welcome.class).withIntent(intent).create().get();

}

}

All tests pass. Now I am going to do the same for the second fragment.

@RunWith(RobolectricGradleTestRunner.class)

@Config(constants = BuildConfig.class,sdk = 21)

public class RegisterFragmentTest {

MainActivity activity;

Button loginButton;

Welcome welcomeActivity;

EditText emailEntry;

@Before

public void setUp() throws Exception {

activity = Robolectric.setupActivity(MainActivity.class);

loginButton = getButton(activity,R.id.registerBtn);

emailEntry = getEditText(activity,R.id.email);

}

@Test

public void registerFragmentShouldNotBeNull(){

RegisterFragment registerFragment = new RegisterFragment();

startFragment(registerFragment, AppCompatActivity.class);

assertNotNull(registerFragment);

}

@Test

public void shouldHaveEmailEntry(){

assertViewIsVisible(emailEntry);

}

However the test shouldHaveEmailEntry doesn't pass!

java.lang.AssertionError

at org.junit.Assert.fail(Assert.java:86)

at org.junit.Assert.assertTrue(Assert.java:41)

at org.junit.Assert.assertNotNull(Assert.java:712)

at org.junit.Assert.assertNotNull(Assert.java:722)

at team.football.ael.support.Assert.assertViewIsVisible(Assert.java:16)

at team.football.ael.RegisterFragmentTest.shouldHaveEmailEntry(RegisterFragmentTest.java:54)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:497)

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:527)

at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)

at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:265)

at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:191)

at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:56)

at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)

at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)

at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)

at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)

at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:157)

at org.junit.runners.ParentRunner.run(ParentRunner.java:363)

at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)

at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)

at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)

at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:497)

at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

The assertViewIsVisible(...) method comes from this class.

 public class Assert {

public static void assertViewIsVisible(View view){

assertNotNull(view);

assertThat(view.getVisibility(),equalTo(View.VISIBLE));

}

}

This is how attach my fragments.

public class MainActivity extends AppCompatActivity {

public static final String LOGIN_FRAGMENT = "LOGIN_FRAGMENT";

public static final String REGISTER_FRAGMENT = "REGISTER_FRAGMENT";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

setTitle(R.string.login_toolbar_title);

LoginFragment loginFragment = new LoginFragment();

FragmentManager fragmentManager = getSupportFragmentManager();

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

fragmentTransaction.add(android.R.id.content,loginFragment,LOGIN_FRAGMENT);

fragmentTransaction.commit();

}

public void userReg(View view){

RegisterFragment regFragment = new RegisterFragment();

FragmentManager fragmentManager1 = getSupportFragmentManager();

FragmentTransaction fragmentTransaction1 = fragmentManager1.beginTransaction();

fragmentTransaction1.addToBackStack("added");

fragmentTransaction1.replace(android.R.id.content,regFragment,REGISTER_FRAGMENT);

fragmentTransaction1.commit();

}

}

And my RegisterFragment is shown below.

public class RegisterFragment extends Fragment {

private SessionManager session;

EditText etEmail, etUsername, etPassword,etConfirmPassword;

String email, userName, userPass,confirmPassword;

Button registerButton;

SqliteHandler sql;

public RegisterFragment() {

// Required empty public constructor

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

View v = inflater.inflate(R.layout.fragment_register, container, false);

Toolbar myToolbar = (Toolbar) v.findViewById(R.id.toolbar);

((AppCompatActivity)getActivity()).setSupportActionBar(myToolbar);

setHasOptionsMenu(true);

etEmail = (EditText)v.findViewById(R.id.email);

etUsername = (EditText)v.findViewById(R.id.user_name);

etPassword = (EditText)v.findViewById(R.id.user_pass);

etConfirmPassword = (EditText)v.findViewById(R.id.confirm_pass);

registerButton = (Button)v.findViewById(R.id.registerBtn);

session = new SessionManager(getActivity());

if (session.isLoggedIn()) {

// User ites already logged in. Take him to main activity

Intent intent = new Intent(getActivity(), Welcome.class);

startActivity(intent);

}

registerButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

email = etEmail.getText().toString();

userName = etUsername.getText().toString();

userPass = etPassword.getText().toString();

confirmPassword = etConfirmPassword.getText().toString();

if(userPass.equals(confirmPassword)){

registerUser(email, userName, userPass, confirmPassword);

getUserId();

}else{

Toast.makeText(getActivity(),"Passwords don't match",Toast.LENGTH_SHORT).show();

}

}

});

return v;

}

private void registerUser(final String email, final String userName,

final String password,final String confirmPassword) {

String tag_string_req = "req_register";

StringRequest strReq = new StringRequest(Request.Method.POST,

Config.URL_REGISTER, new Response.Listener<String>() {

@Override

public void onResponse(String response) {

Log.d("Response", "Register Response: " + response.toString());

try {

JSONObject jsonObject = new JSONObject(response);

if (jsonObject.getString("result").equals("success")) {

Toast.makeText(getActivity(),jsonObject.getString("message"), Toast.LENGTH_LONG).show();

//int id = jsonObject.getInt("message");

//Log.d("Theo", id);

//$don = array('result' =>"success","message"=>mysqli_insert_id($con));

SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());

SharedPreferences.Editor editor = settings.edit();

//editor.putString("id", String.valueOf(id));

editor.putString("email", email);

editor.putString("user_name", userName);

editor.putString("user_pass", password);

editor.putString("confirm_pass", confirmPassword);

editor.commit();

}

else if (jsonObject.getString("result").equals("fail")) {

Toast.makeText(getActivity(),jsonObject.getString("message"), Toast.LENGTH_LONG).show();

}

}catch(JSONException e){

e.printStackTrace();

}

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) {

Log.e("Error", "Registration Error: " + error.getMessage());

Toast.makeText(getActivity(),

error.getMessage(), Toast.LENGTH_LONG).show();

}

}) {

@Override

protected Map<String, String> getParams() {

// Posting params to register url

Map<String, String> params = new HashMap<String, String>();

params.put("id", "");

params.put("email", email);

params.put("user_name", userName);

params.put("user_pass", password);

params.put("confirm_pass", confirmPassword);

return params;

}

};

// Adding request to request queue

AppController.getInstance().addToRequestQueue(strReq, tag_string_req);

}

public void getUserId(){

JsonArrayRequest jsonObjReq = new JsonArrayRequest(Request.Method.GET,

URL.GET_PLAYER_ID,

new Response.Listener<JSONArray>() {

@Override

public void onResponse(JSONArray response) {

Log.d("TAG", response.toString());

try {

for(int i = 0; i<response.length(); i++){

JSONObject jsonObject = response.getJSONObject(i);

int userId = jsonObject.getInt("id");

Log.v("Theo", String.valueOf(userId));

}

} catch (JSONException e) {

e.printStackTrace();

}

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) {

}

});

// Adding request to request queue

AppController.getInstance().addToRequestQueue(jsonObjReq);

}

}

Any ideas why my junit doesn't pass?

Thanks,

Theo

网友答案:

The first test class starts your MainActivity and do some tests. The second test class does again tests on MainActivity. And both activities are initiated with LoginFragment.

I guess you miss a call for userReg(View view) to start the RegFragment.

Your test methods *FragmentShouldNotBeNull makes not much sense because they could be reduced to:

RegisterFragment registerFragment = new RegisterFragment();
assertNotNull(registerFragment);

Robolectric does not support to start new activities from an existing one. It catch all intents and makes them available but don't execute them. So following lines have no real effect in robolectric.

if (session.isLoggedIn()) { 
    ...
    startActivity(intent); 
}
相关阅读:
Top