Skip to content

Commit 2872fc0

Browse files
committed
More Android Unitests
1 parent dec9ed7 commit 2872fc0

9 files changed

Lines changed: 594 additions & 84 deletions

File tree

lib/android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ dependencies {
112112
testImplementation 'org.assertj:assertj-core:3.11.1'
113113
testImplementation 'org.mockito:mockito-core:4.0.0'
114114
testImplementation 'com.squareup.assertj:assertj-android:1.2.0'
115-
testImplementation 'org.mockito:mockito-inline:3.4.0'
115+
testImplementation 'org.mockito:mockito-inline:5.2.0'
116116
testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"
117117
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlinVersion"
118118

@@ -122,7 +122,7 @@ dependencies {
122122

123123
androidTestImplementation "androidx.test.espresso:espresso-core:3.6.1"
124124

125-
androidTestImplementation 'org.mockito:mockito-android:5.18.0'
125+
androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito-inline:2.28.4"
126126

127127
androidTestImplementation "androidx.test.uiautomator:uiautomator:2.3.0"
128128

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.reactnativenavigation;
2+
3+
import android.app.Activity;
4+
import android.content.Context;
5+
import android.view.View;
6+
import android.view.ViewGroup;
7+
8+
import androidx.annotation.NonNull;
9+
10+
import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
11+
import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
12+
import com.reactnativenavigation.mocks.TitleBarButtonCreatorMock;
13+
import com.reactnativenavigation.mocks.TypefaceLoaderMock;
14+
import com.reactnativenavigation.options.Options;
15+
import com.reactnativenavigation.options.params.Bool;
16+
import com.reactnativenavigation.utils.RenderChecker;
17+
import com.reactnativenavigation.viewcontrollers.stack.StackPresenter;
18+
import com.reactnativenavigation.react.events.EventEmitter;
19+
import com.reactnativenavigation.utils.CompatUtils;
20+
import com.reactnativenavigation.utils.ImageLoader;
21+
import com.reactnativenavigation.utils.UiUtils;
22+
import com.reactnativenavigation.viewcontrollers.child.ChildControllersRegistry;
23+
import com.reactnativenavigation.viewcontrollers.viewcontroller.ViewController;
24+
import com.reactnativenavigation.viewcontrollers.stack.topbar.button.IconResolver;
25+
import com.reactnativenavigation.viewcontrollers.stack.StackControllerBuilder;
26+
import com.reactnativenavigation.viewcontrollers.stack.topbar.TopBarController;
27+
import com.reactnativenavigation.views.stack.StackLayout;
28+
import com.reactnativenavigation.views.stack.topbar.TopBar;
29+
30+
import org.mockito.Mockito;
31+
32+
public class TestUtils {
33+
public static StackControllerBuilder newStackController(Activity activity) {
34+
TopBarController topBarController = new TopBarController() {
35+
@Override
36+
protected TopBar createTopBar(@NonNull Context context, @NonNull StackLayout stackLayout) {
37+
TopBar topBar = super.createTopBar(context, stackLayout);
38+
topBar.layout(0, 0, 1000, UiUtils.getTopBarHeight(context));
39+
return topBar;
40+
}
41+
};
42+
return new StackControllerBuilder(activity, Mockito.mock(EventEmitter.class))
43+
.setId("stack" + CompatUtils.generateViewId())
44+
.setChildRegistry(new ChildControllersRegistry())
45+
.setTopBarController(topBarController)
46+
.setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(),
47+
new TopBarBackgroundViewCreatorMock(), new TitleBarButtonCreatorMock(),
48+
new IconResolver(activity, new ImageLoader()), new TypefaceLoaderMock(), new RenderChecker(),
49+
new Options()))
50+
.setInitialOptions(new Options());
51+
}
52+
53+
public static void hideBackButton(ViewController<?> viewController) {
54+
viewController.options.topBar.buttons.back.visible = new Bool(false);
55+
}
56+
57+
public static <T extends View> T spyOn(T child) {
58+
ViewGroup parent = (ViewGroup) child.getParent();
59+
int indexOf = parent.indexOfChild(child);
60+
parent.removeView(child);
61+
T spy = Mockito.spy(child);
62+
parent.addView(spy, indexOf);
63+
return spy;
64+
}
65+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.reactnativenavigation.mocks;
2+
3+
import android.app.Activity;
4+
5+
import com.reactnativenavigation.options.ComponentOptions;
6+
import com.reactnativenavigation.react.events.ComponentType;
7+
import com.reactnativenavigation.views.stack.topbar.titlebar.TitleBarButtonCreator;
8+
import com.reactnativenavigation.views.stack.topbar.titlebar.TitleBarReactButtonView;
9+
10+
public class TitleBarButtonCreatorMock extends TitleBarButtonCreator {
11+
public TitleBarButtonCreatorMock() {
12+
}
13+
14+
@Override
15+
public TitleBarReactButtonView create(Activity activity, ComponentOptions component) {
16+
return new TitleBarReactButtonView(activity, component) {
17+
@Override
18+
public void sendComponentStart(ComponentType type) {
19+
}
20+
21+
@Override
22+
public void sendComponentStop(ComponentType type) {
23+
}
24+
};
25+
}
26+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.reactnativenavigation.mocks;
2+
3+
import com.reactnativenavigation.views.stack.topbar.titlebar.TitleBarReactViewCreator;
4+
5+
public class TitleBarReactViewCreatorMock extends TitleBarReactViewCreator {
6+
public TitleBarReactViewCreatorMock() {
7+
}
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.reactnativenavigation.mocks;
2+
3+
import com.reactnativenavigation.views.stack.topbar.TopBarBackgroundViewCreator;
4+
5+
public class TopBarBackgroundViewCreatorMock extends TopBarBackgroundViewCreator {
6+
public TopBarBackgroundViewCreatorMock() {
7+
}
8+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.reactnativenavigation.mocks;
2+
3+
import android.content.Context;
4+
import android.graphics.Typeface;
5+
import com.reactnativenavigation.options.parsers.TypefaceLoader;
6+
import org.mockito.Mockito;
7+
8+
import java.util.Map;
9+
10+
public class TypefaceLoaderMock extends TypefaceLoader {
11+
private Map<String, Typeface> mockTypefaces;
12+
13+
public TypefaceLoaderMock() {
14+
super(Mockito.mock(Context.class));
15+
}
16+
17+
public TypefaceLoaderMock(Map<String, Typeface> mockTypefaces) {
18+
this();
19+
this.mockTypefaces = mockTypefaces;
20+
}
21+
22+
@Override
23+
public Typeface getDefaultTypeFace() {
24+
return Typeface.DEFAULT;
25+
}
26+
27+
@Override
28+
public Typeface getTypeFace(String fontFamilyName, String fontStyle, String fontWeight, Typeface defaultTypeFace) {
29+
if (mockTypefaces != null && mockTypefaces.containsKey(fontFamilyName)) {
30+
return mockTypefaces.get(fontFamilyName);
31+
}
32+
return defaultTypeFace;
33+
}
34+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package com.reactnativenavigation.viewcontrollers.child;
2+
3+
import androidx.test.ext.junit.rules.ActivityScenarioRule;
4+
import androidx.test.ext.junit.runners.AndroidJUnit4;
5+
import androidx.test.platform.app.InstrumentationRegistry;
6+
import androidx.test.core.app.ActivityScenario;
7+
8+
import com.reactnativenavigation.BaseAndroidTest;
9+
import com.reactnativenavigation.TestActivity;
10+
import com.reactnativenavigation.mocks.SimpleViewController;
11+
import com.reactnativenavigation.options.Options;
12+
import com.reactnativenavigation.viewcontrollers.viewcontroller.Presenter;
13+
import com.reactnativenavigation.viewcontrollers.parent.ParentController;
14+
15+
import org.junit.Before;
16+
import org.junit.Rule;
17+
import org.junit.Test;
18+
import org.junit.runner.RunWith;
19+
import org.mockito.Mockito;
20+
21+
import static org.mockito.ArgumentMatchers.any;
22+
import static org.mockito.Mockito.spy;
23+
import static org.mockito.Mockito.times;
24+
import static org.mockito.Mockito.verify;
25+
26+
@RunWith(AndroidJUnit4.class)
27+
public class ChildControllerTest extends BaseAndroidTest {
28+
private ChildController<?> uut;
29+
private ChildControllersRegistry childRegistry;
30+
private Presenter presenter;
31+
private Options resolvedOptions = new Options();
32+
33+
@Rule
34+
public ActivityScenarioRule<TestActivity> rule = new ActivityScenarioRule<>(TestActivity.class);
35+
36+
@Before
37+
public void beforeEach() {
38+
rule.getScenario().onActivity(activity -> {
39+
childRegistry = spy(new ChildControllersRegistry());
40+
presenter = Mockito.mock(Presenter.class);
41+
uut = new SimpleViewController(activity, childRegistry, "childId", presenter, new Options()) {
42+
@Override
43+
public Options resolveCurrentOptions() {
44+
return resolvedOptions;
45+
}
46+
};
47+
ParentController<?> parent = Mockito.mock(ParentController.class);
48+
Mockito.when(parent.resolveChildOptions(uut)).thenReturn(Options.EMPTY);
49+
uut.setParentController(parent);
50+
});
51+
}
52+
53+
@Test
54+
public void onViewAppeared() {
55+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> uut.onViewWillAppear());
56+
verify(childRegistry, times(1)).onViewAppeared(uut);
57+
}
58+
59+
@Test
60+
public void onViewDisappear() {
61+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
62+
uut.onViewWillAppear();
63+
uut.onViewDisappear();
64+
});
65+
verify(childRegistry, times(1)).onViewDisappear(uut);
66+
}
67+
68+
@Test
69+
public void mergeOptions() {
70+
try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
71+
scenario.onActivity(activity -> {
72+
activity.setContentView(uut.getView());
73+
Options options = new Options();
74+
uut.mergeOptions(options);
75+
verify(presenter).mergeOptions(uut, options);
76+
});
77+
}
78+
}
79+
80+
@Test
81+
public void mergeOptions_emptyOptionsAreIgnored() {
82+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
83+
uut.mergeOptions(Options.EMPTY);
84+
verify(presenter, times(0)).mergeOptions(any(), any());
85+
});
86+
}
87+
88+
@Test
89+
public void mergeOptions_mergeWithParentViewController() {
90+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
91+
Options options = new Options();
92+
uut.mergeOptions(options);
93+
verify(uut.getParentController()).mergeChildOptions(options, uut);
94+
});
95+
}
96+
97+
@Test
98+
public void destroy() {
99+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> uut.destroy());
100+
verify(childRegistry).onChildDestroyed(uut);
101+
}
102+
}

0 commit comments

Comments
 (0)