2016-07-06 69 views
2

在我的应用程序中,我有一个登录和一个寄存器片段。我想测试他们的观点,即如果编辑文本有提示,他们的按钮。我将通过包含两个editi文本和一个按钮的登录片段放在这里。还有一个webservice,但我会在稍后测试它。用Robolectric 3.0测试片段的视图

public class LoginFragment extends Fragment { 

Button loginButton; 
EditText etName,etPass; 
String login_name; 
String login_pass; 
private SessionManager session; 
TextView forgotPassBtn; 

public LoginFragment() { 
    // 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_login, container, false); 
    Toolbar myToolbar = (Toolbar) v.findViewById(R.id.toolbar); 
    ((AppCompatActivity)getActivity()).setSupportActionBar(myToolbar); 
    setHasOptionsMenu(true); 
    etName = (EditText)v.findViewById(R.id.user_name); 
    etPass = (EditText)v.findViewById(R.id.user_pass); 
    loginButton = (Button) v.findViewById(R.id.loginButton); 

    login_name = etName.getText().toString(); 
    login_pass = etName.getText().toString(); 

    forgotPassBtn = (TextView) v.findViewById(R.id.forgotPass); 

    session = new SessionManager(getActivity()); 

    if (session.isLoggedIn()) { 
     // User is already logged in. Take him to main activity 
     Intent intent = new Intent(getActivity(), Welcome.class); 
     startActivity(intent); 
     getActivity().finish(); 
    } 
    loginButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      login_name = etName.getText().toString(); 
      login_pass = etPass.getText().toString(); 

      SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
      SharedPreferences.Editor editor = settings.edit(); 

      if(login_name.isEmpty() && login_pass.isEmpty()) { 
       Toast.makeText(getActivity(),"Username η κωδικός είναι κενό",Toast.LENGTH_SHORT).show(); 
      }else { 
       editor.putString("id", ""); 
       editor.putString("user_name", login_name); 
       editor.putString("user_pass", login_pass); 
       editor.commit(); 

       loginUser(login_name, login_pass); 
      } 
     } 
    }); 
    return v; 

} 



private void loginUser(final String userName, 
         final String password) { 
    /* 
    Tag used to cancel the request 
    HttpsTrustManager.sssMethod(); 
    */ 
    String tag_string_req = "req_register"; 


    StringRequest strReq = new StringRequest(Request.Method.POST, 
      Config.URL_LOGIN, 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")) { 
        session.setLogin(true); 
        Toast.makeText(getActivity(), jsonObject.getString("message"), Toast.LENGTH_LONG).show(); 
        Intent intent = new Intent(getActivity(), 
          Welcome.class); 
        startActivity(intent); 
        getActivity().finish(); 
       } 

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

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

       } 

      }catch(JSONException e){ 
       e.printStackTrace(); 
      } 
      // Launch login activity 


      //Toast.makeText(getApplicationContext(), "User successfully registered. Try login now!", Toast.LENGTH_LONG).show(); 

     } 


    }, 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("user_name", userName); 
      params.put("user_pass", password); 

      return params; 
     } 

    }; 

    // Adding request to request queue 
    AppController.getInstance().addToRequestQueue(strReq, tag_string_req); 
} 

}

现在,我做了一些测试与Robolectric。

@RunWith(RobolectricGradleTestRunner.class) 
@Config(constants = BuildConfig.class,sdk = 21) 
public class LoginFragmentTest { 
MainActivity activity; 
Button loginButton; 

@Before 
public void setUp() throws Exception { 
    activity = Robolectric.setupActivity(MainActivity.class); 
    loginButton = getButton(activity,R.id.registerBtn); 
} 

@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); 
    assertThat(nameEntry.getHint().toString(),equalTo(ResourceLocator.getString(R.string.login_username))); 
} 

}

的getEditText方法在另一个类中定义。

public class ViewLocator { 
public static TextView getTextView(Activity activity, int viewId){ 
    return ((TextView)activity.findViewById(viewId)); 
} 
public static EditText getEditText(Activity activity, int viewId){ 
    return ((EditText)activity.findViewById(viewId)); 
} 
public static Button getButton(Activity activity, int viewId){ 
    return ((Button) activity.findViewById(viewId)); 
} 

}

当我运行LoginFragmentTest我上shouldHaveUserNameEntry()方法

java.lang.NullPointerException 
at team.football.ael.LoginFragmentTest.shouldHaveUserNameEntry(LoginFragmentTest.java:50) 
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:69) 
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) 

任何想法如何成功地测试编辑文本视图中的错误?

 assertViewIsVisible(nameEntry); 

通行证。出现在

 assertThat(nameEntry.getHint().toString(),equalTo(ResourceLocator.getString(R.string.login_username))); 

感谢,

西奥错误。

+0

您的片段,我想'getHint()'返回null.Is它浮编辑测试标签?如果是这样,你应该问问布局而不是编辑文本 –

回答

2

在这里,你由startFragment方法

@Test 
public void loginFragmentShouldNotBeNull() { 
LoginFragment loginFragment = new LoginFragment(); 
startFragment(loginFragment, AppCompatActivity.class); 
assertNotNull(loginFragment); 
} 

然后尝试找到在MainActivity的USER_NAME字段初始化的AppCompactActivity添加你登录的片段。你在AppCompatActivity上添加了你的片段,而不是在你的MainActivity上(我想你在你的MainActivity中动态添加你的片段)。所以EditText不存在

@Test 
public void shouldHaveUserNameEntry() throws Exception { 
EditText nameEntry = getEditText(activity,R.id.user_name); 
assertViewIsVisible(nameEntry); 
      assertThat(nameEntry.getHint().toString(),equalTo(ResourceLocator.getString(R.string.login_username))); 
} 

我不认为你需要测试你的MainActivity。你可以使用从SupportFragmentTestUtil方法startVisibleFragment其初始化上AppCompatActivity

@RunWith(RobolectricGradleTestRunner.class) 
@Config(constants = BuildConfig.class,sdk = 21) 
public class LoginFragmentTest { 

private LoginFragment mLoginFragment = new LoginFragment(); 

@Before 
public void setUp() throws Exception { 
    SupportFragmentTestUtil.startVisibleFragment(mLoginFragment); 
} 

@Test 
public void shouldHaveUserNameEntry() throws Exception{ 
    EditText nameEntry = mLoginFragment.getActivity().findViewById(R.id.user_name); 
    assertViewIsVisible(nameEntry); 
    assertThat(nameEntry.getHint().toString(),equalTo(RuntimeEnvironment.application.getResources().getString(R.string.login_username))); 
} 
+0

请指出你的设置有什么不同,以及如何解决这个问题。 – Egor

+0

我已经完成了我的回答 –

+0

是的。感谢这位先生。它正在工作:) :) – Theo