Skip to content

Commit 1f60477

Browse files
author
Daniel Novak
authored
Merge pull request #36 from inloop/unit_test
Add basic instrumented test
2 parents 3f4a945 + a53e967 commit 1f60477

File tree

12 files changed

+393
-23
lines changed

12 files changed

+393
-23
lines changed

library/build.gradle

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ apply plugin: 'maven'
33

44
android {
55
compileSdkVersion 26
6-
buildToolsVersion '25.0.3'
6+
buildToolsVersion '26.0.2'
77

88
defaultConfig {
99
minSdkVersion 15
1010
targetSdkVersion 26
1111
versionCode 1
1212
versionName VERSION_NAME
1313
consumerProguardFiles 'proguard-rules.pro'
14+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1415
}
1516
compileOptions {
1617
sourceCompatibility JavaVersion.VERSION_1_7
@@ -20,13 +21,17 @@ android {
2021
}
2122

2223
dataBinding {
23-
enabled = true;
24+
enabled = true
2425
}
2526
}
2627

2728
dependencies {
28-
compile 'com.android.support:support-fragment:26.0.1'
29-
compile 'com.android.support:appcompat-v7:26.0.1'
29+
compile 'com.android.support:support-fragment:26.1.0'
30+
compile 'com.android.support:appcompat-v7:26.1.0'
31+
32+
androidTestCompile 'junit:junit:4.12'
33+
androidTestCompile 'com.android.support.test:runner:1.0.1'
34+
androidTestCompile 'com.android.support.test:rules:1.0.1'
3035
}
3136

3237
task androidJavadocs(type: Javadoc) {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="eu.inloop.viewmodel" >
4+
5+
<application>
6+
<activity android:name=".fixture.activity.VMTestActivity" android:theme="@style/Theme.AppCompat" />
7+
</application>
8+
</manifest>
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package eu.inloop.viewmodel;
2+
3+
4+
import android.content.pm.ActivityInfo;
5+
import android.support.test.InstrumentationRegistry;
6+
import android.support.test.filters.MediumTest;
7+
import android.support.test.filters.SmallTest;
8+
import android.support.test.rule.ActivityTestRule;
9+
import android.support.test.runner.AndroidJUnit4;
10+
11+
import org.junit.Rule;
12+
import org.junit.Test;
13+
import org.junit.runner.RunWith;
14+
15+
import java.util.Map;
16+
17+
import eu.inloop.viewmodel.fixture.activity.VMTestActivity;
18+
19+
import static org.hamcrest.CoreMatchers.is;
20+
import static org.hamcrest.CoreMatchers.notNullValue;
21+
import static org.hamcrest.CoreMatchers.nullValue;
22+
import static org.hamcrest.MatcherAssert.assertThat;
23+
24+
25+
@RunWith(AndroidJUnit4.class)
26+
public final class ViewModelActivityTest {
27+
28+
@Rule
29+
public final ActivityTestRule<VMTestActivity> mActivityTestRule =
30+
new ActivityTestRule<>(VMTestActivity.class, false, false);
31+
32+
@SmallTest
33+
@Test
34+
public void viewModelActivity_onBindView_test() {
35+
mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), true));
36+
37+
assertThat(mActivityTestRule.getActivityResult().getResultCode(), is(VMTestActivity.RESULT_CODE_OK));
38+
}
39+
40+
@SmallTest
41+
@Test
42+
public void viewModelActivity_getViewModel_getView_test() {
43+
mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
44+
mActivityTestRule.getActivity().getViewModel().loadData();
45+
46+
assertThat(mActivityTestRule.getActivityResult().getResultCode(), is(VMTestActivity.RESULT_CODE_OK));
47+
}
48+
49+
@SmallTest
50+
@Test
51+
public void viewModelActivity_getViewModel_getViewOptional_test() {
52+
mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
53+
mActivityTestRule.getActivity().getViewModel().loadDataOptional();
54+
55+
assertThat(mActivityTestRule.getActivityResult().getResultCode(), is(VMTestActivity.RESULT_CODE_OK));
56+
}
57+
58+
@SmallTest
59+
@Test
60+
public void viewModelActivity_clearView_test() {
61+
mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
62+
mActivityTestRule.getActivity().getViewModel().clearView();
63+
64+
assertThat(mActivityTestRule.getActivity().getViewModel().getView(), is(nullValue()));
65+
}
66+
67+
@SmallTest
68+
@Test
69+
public void viewModelActivity_uniqueIdentifier_test() {
70+
mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
71+
String uniqueIdentifier = mActivityTestRule.getActivity().getViewModel().getUniqueIdentifier();
72+
73+
assertThat(uniqueIdentifier, is(notNullValue()));
74+
}
75+
76+
@SmallTest
77+
@Test
78+
public void viewModelActivity_fragment_getView_test() {
79+
mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
80+
81+
mActivityTestRule.getActivity().getTestFragment().getViewModel().loadData();
82+
83+
assertThat(mActivityTestRule.getActivityResult().getResultCode(), is(VMTestActivity.RESULT_CODE_OK));
84+
}
85+
86+
@SmallTest
87+
@Test
88+
public void viewModelActivity_fragment_remove_test() {
89+
mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
90+
91+
String uniqueIdentifierActivity = mActivityTestRule.getActivity().getViewModel().getUniqueIdentifier();
92+
String uniqueIdentifierFragment = mActivityTestRule.getActivity().getTestFragment().getViewModel().getUniqueIdentifier();
93+
94+
Map<String, AbstractViewModel<? extends IView>> viewModels =
95+
mActivityTestRule.getActivity().getViewModelProvider().getViewModels();
96+
97+
assertThat(viewModels.containsKey(uniqueIdentifierActivity), is(true));
98+
assertThat(viewModels.containsKey(uniqueIdentifierFragment), is(true));
99+
100+
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
101+
@Override
102+
public void run() {
103+
mActivityTestRule.getActivity().removeTestFragment();
104+
}
105+
});
106+
107+
//Check If ViewModel is removed after removing fragment
108+
viewModels = mActivityTestRule.getActivity().getViewModelProvider().getViewModels();
109+
110+
assertThat(viewModels.containsKey(uniqueIdentifierActivity), is(true));
111+
assertThat(viewModels.containsKey(uniqueIdentifierFragment), is(false));
112+
}
113+
114+
@SmallTest
115+
@Test
116+
public void viewModelActivity_fragment_model_state_test() {
117+
mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
118+
119+
final int stateValue = 1;
120+
mActivityTestRule.getActivity().getTestFragment().getViewModel().setStateValue(stateValue);
121+
122+
rotateScreen(1);
123+
124+
int actualStateValue = mActivityTestRule.getActivity().getTestFragment().getViewModel().getStateValue();
125+
126+
assertThat(stateValue, is(actualStateValue));
127+
}
128+
129+
@MediumTest
130+
@Test
131+
public void viewModelActivity_instance_count_test() {
132+
mActivityTestRule.launchActivity(VMTestActivity.makeIntent(InstrumentationRegistry.getContext(), false));
133+
134+
String uniqueIdentifierActivity = mActivityTestRule.getActivity().getViewModel().getUniqueIdentifier();
135+
String uniqueIdentifierFragment = mActivityTestRule.getActivity().getTestFragment().getViewModel().getUniqueIdentifier();
136+
137+
rotateScreen(5);
138+
139+
Map<String, AbstractViewModel<? extends IView>> viewModels =
140+
mActivityTestRule.getActivity().getViewModelProvider().getViewModels();
141+
142+
assertThat(viewModels.size(), is(2)); //activity + fragment
143+
144+
assertThat(viewModels.containsKey(uniqueIdentifierActivity), is(true));
145+
assertThat(viewModels.containsKey(uniqueIdentifierFragment), is(true));
146+
}
147+
148+
private void rotateScreen(int numOfTimes) {
149+
for (int i = 0; i < numOfTimes; i++) {
150+
mActivityTestRule.getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
151+
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
152+
mActivityTestRule.getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
153+
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
154+
}
155+
}
156+
157+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package eu.inloop.viewmodel.fixture.activity;
2+
3+
import eu.inloop.viewmodel.IView;
4+
5+
public interface IVMTestActivityView extends IView {
6+
7+
void onLoadData(boolean loaded);
8+
9+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package eu.inloop.viewmodel.fixture.activity;
2+
3+
import android.content.Context;
4+
import android.content.Intent;
5+
import android.os.Bundle;
6+
import android.support.annotation.NonNull;
7+
import android.support.annotation.Nullable;
8+
import android.support.v4.app.Fragment;
9+
import android.widget.LinearLayout;
10+
11+
import eu.inloop.viewmodel.base.ViewModelBaseActivity;
12+
import eu.inloop.viewmodel.fixture.fragment.VMTestFragment;
13+
14+
public class VMTestActivity extends ViewModelBaseActivity<IVMTestActivityView, VMTestActivityViewModel> implements IVMTestActivityView {
15+
16+
public static final int RESULT_CODE_OK = 1;
17+
public static final String EXTRA_CALL_ON_BIND = "EXTRA_CALL_ON_BIND";
18+
19+
@NonNull
20+
public static Intent makeIntent(@NonNull Context context, boolean callOnBindModel) {
21+
Intent intent = new Intent(context, VMTestActivity.class);
22+
intent.putExtra(EXTRA_CALL_ON_BIND, callOnBindModel);
23+
24+
return intent;
25+
}
26+
27+
@Override
28+
protected void onCreate(@Nullable Bundle savedInstanceState) {
29+
super.onCreate(savedInstanceState);
30+
31+
LinearLayout view = new LinearLayout(this);
32+
view.setId(android.R.id.content);
33+
setContentView(view);
34+
35+
if (savedInstanceState == null) {
36+
addTestFragment();
37+
}
38+
39+
setModelView(this);
40+
}
41+
42+
public void addTestFragment() {
43+
getSupportFragmentManager()
44+
.beginTransaction()
45+
.add(android.R.id.content, new VMTestFragment())
46+
.commitNow();
47+
}
48+
49+
public void removeTestFragment() {
50+
getSupportFragmentManager()
51+
.beginTransaction()
52+
.remove(getTestFragment())
53+
.commitNow();
54+
}
55+
56+
@NonNull
57+
public VMTestFragment getTestFragment() {
58+
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
59+
if (fragment instanceof VMTestFragment) {
60+
return (VMTestFragment) fragment;
61+
}
62+
}
63+
throw new AssertionError("Fragment not found");
64+
}
65+
66+
@Override
67+
public void onLoadData(boolean loaded) {
68+
setResult(RESULT_CODE_OK);
69+
finish();
70+
}
71+
72+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package eu.inloop.viewmodel.fixture.activity;
2+
3+
import android.os.Bundle;
4+
import android.support.annotation.NonNull;
5+
import android.support.annotation.Nullable;
6+
7+
import eu.inloop.viewmodel.AbstractViewModel;
8+
9+
public class VMTestActivityViewModel extends AbstractViewModel<IVMTestActivityView> {
10+
11+
private boolean mCallOnBind;
12+
13+
@Override
14+
public void onCreate(@Nullable Bundle arguments, @Nullable Bundle savedInstanceState) {
15+
super.onCreate(arguments, savedInstanceState);
16+
if (arguments == null) {
17+
throw new AssertionError("Arguments must be set for this ViewModel");
18+
}
19+
mCallOnBind = arguments.getBoolean(VMTestActivity.EXTRA_CALL_ON_BIND);
20+
}
21+
22+
@Override
23+
public void onBindView(@NonNull IVMTestActivityView view) {
24+
super.onBindView(view);
25+
26+
if (mCallOnBind) {
27+
loadData();
28+
}
29+
}
30+
31+
public void loadData() {
32+
getView().onLoadData(true);
33+
}
34+
35+
public void loadDataOptional() {
36+
getViewOptional().onLoadData(true);
37+
}
38+
39+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package eu.inloop.viewmodel.fixture.fragment;
2+
3+
import eu.inloop.viewmodel.IView;
4+
5+
public interface IVMTestFragmentView extends IView {
6+
7+
void onLoadData(boolean loaded);
8+
9+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package eu.inloop.viewmodel.fixture.fragment;
2+
3+
import android.os.Bundle;
4+
import android.support.annotation.Nullable;
5+
import android.view.LayoutInflater;
6+
import android.view.View;
7+
import android.view.ViewGroup;
8+
import android.widget.LinearLayout;
9+
10+
import eu.inloop.viewmodel.base.ViewModelBaseFragment;
11+
import eu.inloop.viewmodel.fixture.activity.VMTestActivity;
12+
13+
public class VMTestFragment extends ViewModelBaseFragment<IVMTestFragmentView, VMTestFragmentViewModel>
14+
implements IVMTestFragmentView {
15+
16+
@Nullable
17+
@Override
18+
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
19+
return new LinearLayout(getContext());
20+
}
21+
22+
@Override
23+
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
24+
super.onViewCreated(view, savedInstanceState);
25+
setModelView(this);
26+
}
27+
28+
@Override
29+
public void onLoadData(boolean loaded) {
30+
getActivity().setResult(VMTestActivity.RESULT_CODE_OK);
31+
getActivity().finish();
32+
}
33+
}

0 commit comments

Comments
 (0)