-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Request] Please add a unit test for the sample project #60
Comments
I like to keep the unit tests of ViewModels simple without Rx dependencies. LoginViewModel loginViewModel = new LoginViewModel();
loginViewModel.email.set("invalid@invalid");
assertEquals("Invalid email", loginViewModel.emailError.get()); However, the dependent values ( The Then the code will become Other way is to write a This example should give you a good idea. public class LoginViewModelTest {
private LoginViewModel sut;
private Api mockApi;
private BehaviorSubject<Result<LoginResult>> apiDriver;
private Navigator mockNavigator;
private LoginResult successResult;
private Session mockSession;
private BehaviorSubject<Result<Object>> generateOtpApiDriver;
private MessageHelper mockMessageHelper;
@Before
public void setUp() throws Exception {
mockSession = mock(Session.class);
mockMessageHelper = mock(MessageHelper.class);
successResult = new LoginResult(10, "some_token");
mockApi = mock(Api.class);
apiDriver = BehaviorSubject.create();
generateOtpApiDriver = BehaviorSubject.create();
when(mockApi.login(any(LoginRequest.class))).thenReturn(apiDriver.firstOrError());
when(mockApi.generateOtp(any(OtpRequest.class))).thenReturn(generateOtpApiDriver.firstOrError());
mockNavigator = mock(Navigator.class);
sut = new LoginViewModel(mockApi, mockNavigator, mockSession, mockMessageHelper);
subscribe(sut.getEmailError(), sut.getPasswordError());
}
@Test
public void email_valid() throws Exception {
sut.getEmail().set("[email protected]");
sut.getLoginClick().run();
assertEquals("", sut.getEmailError().get());
}
@Test
public void email_invalid() throws Exception {
sut.getEmail().set("abc_co");
assertEquals("", sut.getEmailError().get());
sut.getLoginClick().run();
assertEquals("Invalid email format", sut.getEmailError().get());
}
@Test
public void password_valid() throws Exception {
sut.getPassword().set("abc_co");
sut.getLoginClick().run();
assertEquals("", sut.getPasswordError().get());
}
@Test
public void password_invalid() throws Exception {
sut.getPassword().set("");
assertEquals("", sut.getPasswordError().get());
sut.getLoginClick().run();
assertEquals("Password cannot be empty", sut.getPasswordError().get());
}
@Test
public void loginClick_ShouldNotInvokeLoginApi_invalidInput() throws Exception {
sut.getEmail().set("testcom");
sut.getPassword().set("testpass");
sut.getLoginClick().run();
verifyNoMoreInteractions(mockApi);
}
@Test
public void loginClick_ShouldInvokeLoginApi_validInput() throws Exception {
sut.getEmail().set("[email protected]");
sut.getPassword().set("testpass");
sut.getLoginClick().run();
verify(mockApi).login(argThat(new ArgumentMatcher<LoginRequest>() {
@Override
public boolean matches(LoginRequest argument) {
return argument.email.equals("[email protected]") &&
argument.password.equals("testpass");
}
}));
}
@Test
public void navigateToHome_onLoginSuccess() throws Exception {
sut.getEmail().set("[email protected]");
sut.getPassword().set("123");
sut.getLoginClick().run();
apiDriver.onNext(ResultFactory.success(successResult));
verify(mockNavigator).navigateToHome();
}
@Test
public void storesAccessToken_onLoginSuccess() throws Exception {
sut.getEmail().set("[email protected]");
sut.getPassword().set("123");
sut.getLoginClick().run();
apiDriver.onNext(ResultFactory.success(successResult));
verify(mockSession).storeAccessToken(successResult.userId, successResult.accessToken);
}
@Test
public void displaysError_onLoginFailure() throws Exception {
TestObserver<String> errorObserver = sut.getLoadingVM().errorMessage.test();
sut.getEmail().set("[email protected]");
sut.getPassword().set("123");
sut.getLoginClick().run();
apiDriver.onNext(ResultFactory.<LoginResult>validationError("Not found"));
verify(mockNavigator, never()).navigateToHome();
errorObserver.assertValue("Not found");
}
@Test
public void displaysProgress_duringLogin() throws Exception {
sut.getEmail().set("[email protected]");
sut.getPassword().set("123");
assertFalse(sut.getLoadingVM().progressVisible.get());
sut.getLoginClick().run();
assertTrue(sut.getLoadingVM().progressVisible.get());
apiDriver.onNext(ResultFactory.<LoginResult>httpErrorUnknown());
assertFalse(sut.getLoadingVM().progressVisible.get());
}
@Test
public void generateOneTimePassword_invokesApi() throws Exception {
sut.getEmail().set("[email protected]");
sut.getGenerateOTPClick().run();
verify(mockApi).generateOtp(argThat(new ArgumentMatcher<OtpRequest>() {
@Override
public boolean matches(OtpRequest argument) {
return argument.email.equals("[email protected]");
}
}));
}
@Test
public void displaysMessage_onSuccess() throws Exception {
sut.getEmail().set("[email protected]");
sut.getGenerateOTPClick().run();
verifyNoMoreInteractions(mockMessageHelper);
generateOtpApiDriver.onNext(ResultFactory.success(new Object()));
verify(mockMessageHelper).showMessage("Check email for OTP");
}
@Test
public void displaysProgressAndError_onFailure() throws Exception {
ObservableField<Boolean> progress = sut.getLoadingVM().progressVisible;
TestObserver<String> errorObserver = sut.getLoadingVM().errorMessage.test();
assertFalse(progress.get());
sut.getGenerateOTPClick().run();
assertTrue(progress.get());
generateOtpApiDriver.onNext(ResultFactory.httpErrorUnknown());
assertFalse(progress.get());
errorObserver.assertValue("Something went wrong");
verifyNoMoreInteractions(mockMessageHelper);
}
@Test
public void signup_navigatesToAddUser() throws Exception {
sut.getSignupClick().run();
verify(mockNavigator).navigateToAddUser();
}
} Lets keep this issue open as it is important to have an example in the sample app. |
Thank you for providing a simple solution! |
Hi, your MVVM design is very inspiring.
I made a small sample app which utilizes your modules and Kotlin.
Here is the link https://github.com/mishkaowner/MVVMSample
The only issue I came across is that you are missing a unit test example for your sample application.
I already checked all the test files
ex) https://github.com/manas-chaudhari/android-mvvm/blob/master/android-mvvm/src/test/java/com/manaschaudhari/android_mvvm/FieldUtilsTest.java
But I have not found a clear example of a unit test for ViewModel.
val vm = MainViewModel()
vm.edit.set("Hello")
vm.result.toObservable().test().assertValue("You typed Hello")
this is the best test code I made so far...
Please, lead me to the right direction.
Thank you
The text was updated successfully, but these errors were encountered: