I have two fragments attached to an activity.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoginFragment loginFragment = new LoginFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
fragmentTransaction.add(android.R.id.content,loginFragment);
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);
fragmentTransaction1.commit();
}
}
The registration fragment attached via a button. Now I want to test both of them in robolectric 3.0.
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class,sdk = 21)
public class MainActivityTest {
MainActivity activity;
@Before
public void setUp(){
activity= Robolectric.setupActivity(MainActivity.class);
}
@Test
public void shouldNotBeNull(){
assertNotNull(activity);
LoginFragment loginFragment = new LoginFragment();
startFragment(loginFragment);
assertNotNull(loginFragment);
}
@Test
public void loginFragmentShouldNotBeNull(){
RegisterFragment registerFragment = new RegisterFragment();
startFragment(registerFragment);
assertNotNull(registerFragment);
}
@Test
public void registerFragmentShouldNotBeNull(){
RegisterFragment registerFragment = new RegisterFragment();
startFragment(registerFragment);
assertNotNull(registerFragment);
}
}
These line complain
startFragment(loginFragment);
startFragment(registerFragment);
saying that startFragment(android.app.Fragment) can not be applied in LoginFragment and Register fragment respectively.
For both fragments I import
import android.support.v4.app.Fragment;
so this is causing the problem. I could have fix this issue,by using fixed fragments,but how about using dynamic ones?
Any ideas?
Thanks.
EDIT
The error described above is fixed. I just added
import static org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment;
However,when I run the test I get another exception.
java.lang.ClassCastException: org.robolectric.shadows.support.v4.SupportFragmentTestUtil$FragmentUtilActivity cannot be cast to android.support.v7.app.AppCompatActivity
at fragments.LoginFragment.onCreateView(LoginFragment.java:64)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2074)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1286)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1671)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:532)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at org.robolectric.shadows.ShadowMessageQueue.dispatchMessage(ShadowMessageQueue.java:144)
at org.robolectric.shadows.ShadowMessageQueue.access$100(ShadowMessageQueue.java:30)
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:105)
at org.robolectric.util.Scheduler.runOrQueueRunnable(Scheduler.java:293)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:143)
at org.robolectric.shadows.ShadowMessageQueue.enqueueMessage(ShadowMessageQueue.java:126)
at android.os.MessageQueue.enqueueMessage(MessageQueue.java)
at android.os.Handler.enqueueMessage(Handler.java:631)
at android.os.Handler.sendMessageAtTime(Handler.java:600)
at android.os.Handler.sendMessageDelayed(Handler.java:570)
at android.os.Handler.post(Handler.java:326)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1557)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:654)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:621)
at org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment(SupportFragmentTestUtil.java:17)
at team.football.ael.MainActivityTest.loginFragmentShouldNotBeNull(MainActivityTest.java:34)
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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
java.lang.ClassCastException:
org.robolectric.shadows.support.v4.
SupportFragmentTestUtil$FragmentUtilActivity
cannot be cast to android.support.v7.app.AppCompatActivity
at fragments.RegisterFragment.onCreateView(RegisterFragment.java:54)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2074)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1286)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1671)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:532)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at org.robolectric.shadows.ShadowMessageQueue.dispatchMessage(ShadowMessageQueue.java:144)
at org.robolectric.shadows.ShadowMessageQueue.access$100(ShadowMessageQueue.java:30)
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:105)
at org.robolectric.util.Scheduler.runOrQueueRunnable(Scheduler.java:293)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:143)
at org.robolectric.shadows.ShadowMessageQueue.enqueueMessage(ShadowMessageQueue.java:126)
at android.os.MessageQueue.enqueueMessage(MessageQueue.java)
at android.os.Handler.enqueueMessage(Handler.java:631)
at android.os.Handler.sendMessageAtTime(Handler.java:600)
at android.os.Handler.sendMessageDelayed(Handler.java:570)
at android.os.Handler.post(Handler.java:326)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1557)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:654)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:621)
at org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment(SupportFragmentTestUtil.java:17)
at team.football.ael.MainActivityTest.registerFragmentShouldNotBeNull(MainActivityTest.java:41)
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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
EDIT 2
This is my RegisterFragment
public class RegisterFragment extends Fragment {
private SessionManager session;
EditText etEmail, etUsername, etPassword,etConfirmPassword;
String email, userName, userPass,confirmPassword;
Button registerButton;
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.name);
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 manager
// Session manager
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);
}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) {
// Tag used to cancel the request
//HttpsTrustManager.sssMethod();
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();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = settings.edit();
editor.putString("id","");
editor.putString("email", email);
editor.putString("user_name", userName);
editor.putString("user_pass", password);
editor.putString("confirm_pass", confirmPassword);
}
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);
}
}
Robolectric is intended to be fully compatible with Android's official testing libraries since version 4.0. As such we encourage you to try these new APIs and provide feedback. At some point the Robolectric equivalents will be deprecated and removed.
AndroidX Test is a collection of Jetpack libraries that lets you run tests against Android apps. It also provides a series of tools to help you write these tests. For example, AndroidX Test provides JUnit4 rules to start activities and interact with them in JUnit4 tests.
Your fragments inherit from "Support fragments" (the ones from android support library), but your startFragment()
function expects regular fragments. You can use SupportFragmentTestUtil.startFragment(fragment, activityClass)
Support library allows to use fragments on API levels where no fragments were supported yet. If your application is expected to run on API 11 and above (Android 3) - you can derive your fragments from android.app.Fragment
directly
Bit late but for others, this works well for androidx.fragment.app.Fragment and robolectric 4:
@RunWith(RobolectricTestRunner::class)
class YourFragmentTest {
lateinit var yourFragment: YourFragment
@Before
fun setUp() {
val activity = Robolectric.buildActivity(FragmentActivity::class.java)
.create()
.start()
.resume()
.get()
yourFragment = YourFragment()
activity.supportFragmentManager.beginTransaction().apply {
add(yourFragment, "YourFragment")
commit()
}
}
@Test
fun testYourMethod() {
assertTrue(yourFragment.YourMethod())
....
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With