0

I have the following function I want to test :

public void attemptLogin() {
        // Store values at the time of the login attempt.
        String userid = mUserIdView.getText().toString();

        if (TextUtils.isEmpty(userid)) {
            if (mCurrentUser != null) {
                userid = mCurrentUser.getUserId();
            }
        }
}

I want to write a unit test and give the function above an input for the userId. As can be seen, the function is doing :

mUserIdView.getText().toString();

And causes the code to fail because the UI is not loaded (We have UI testing for that) How would you recommend to test it ? Thanks !

Nativ Barak
  • 169
  • 1
  • 14

2 Answers2

2

If you apply dependency injection and this view is injected to class when is instantiated you can create a Mock and then inject it.

Text dummyText = new Text(myText)
View mockedView= mock(View.class);
when(mockedView.getText()).thenReturn(dummyText);

But if you just want some value to get I recomend you use stubs or dummies to make it easier.

Edit:

class MyTextViewStub extends TextView {

    private final CharSequence text;

    public MyTextView(CharSequence text) {
        this.text = text;
    }

    @Override
    public CharSequence getText() {
        return this.text;
    }

}

And you inject this view to class what you want to test.

Pau Trepat
  • 697
  • 1
  • 6
  • 24
  • Thanks for the response ! I think stubs is the best solution for me rn. I can't manage to figure out how to stub this function. Would you mind give me an example for that ? – Nativ Barak Dec 11 '17 at 15:26
  • It should work. getText function is not final then you can overwrite it. Be careful if you want to do more than stub the method because you are making this object behaviour inconsistent – Pau Trepat Dec 11 '17 at 16:28
  • Please if you consider that it answers your question, remember to mark it as a resolved question. – Pau Trepat Dec 13 '17 at 14:29
0

You need to define a mock mUserIdView and then put an expectation on it such that getText() returns "whatever you want it to return".

Assuming your class is the Presenter working on login attempt received from view, it will look something like:

public class MyPresenter {
    private final MyView myView;
    private volatile CurrentUser mCurrentUser;
public MyPresenter(MyView myView) {
    this.myView = myView;
}

public void setCurrentUser(CurrentUser currentUser) {
    this.mCurrentUser = currentUser;
}

public void attemptLogin() {
    // Store values at the time of the login attempt.
    String userid = myView.getText().toString();

    if (TextUtils.isEmpty(userid)) {
        if (mCurrentUser != null) {
            userid = mCurrentUser.getUserId();
        }
    }
}
}

Then in your test case, you will inject a mocked View object during initialization.

Dev Amitabh
  • 185
  • 1
  • 4