Skip to content

Commit b5a448a

Browse files
Add unit tests for ad utilities and native ad loader
1 parent 3fe6eaa commit b5a448a

File tree

2 files changed

+233
-0
lines changed

2 files changed

+233
-0
lines changed

app/src/test/java/com/d4rk/androidtutorials/java/ads/AdUtilsTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,23 @@ public void loadBanner_withAdView_loadsAd() {
5757
verify(adView, times(1)).loadAd(any(AdRequest.class));
5858
}
5959

60+
@Test
61+
public void loadBanner_withAdView_multipleCalls_initializeOnlyOnce() {
62+
Context context = mock(Context.class);
63+
when(context.getApplicationContext()).thenReturn(context);
64+
AdView adView = mock(AdView.class);
65+
when(adView.getContext()).thenReturn(context);
66+
67+
try (MockedStatic<MobileAds> mobileAds = mockStatic(MobileAds.class)) {
68+
AdUtils.loadBanner(adView);
69+
AdUtils.loadBanner(adView);
70+
71+
mobileAds.verify(() -> MobileAds.initialize(context), times(1));
72+
}
73+
74+
verify(adView, times(2)).loadAd(any(AdRequest.class));
75+
}
76+
6077
@Test
6178
public void loadBanner_withNativeAdBannerView_loadsAd() {
6279
Context context = mock(Context.class);
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
package com.d4rk.androidtutorials.java.ads;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertNotNull;
5+
import static org.mockito.ArgumentMatchers.any;
6+
import static org.mockito.ArgumentMatchers.anyString;
7+
import static org.mockito.ArgumentMatchers.eq;
8+
import static org.mockito.Mockito.doAnswer;
9+
import static org.mockito.Mockito.mock;
10+
import static org.mockito.Mockito.mockConstruction;
11+
import static org.mockito.Mockito.mockStatic;
12+
import static org.mockito.Mockito.never;
13+
import static org.mockito.Mockito.times;
14+
import static org.mockito.Mockito.verify;
15+
import static org.mockito.Mockito.when;
16+
17+
import android.content.Context;
18+
import android.graphics.drawable.Drawable;
19+
import android.view.LayoutInflater;
20+
import android.view.View;
21+
import android.view.ViewGroup;
22+
import android.widget.Button;
23+
import android.widget.ImageView;
24+
import android.widget.TextView;
25+
26+
import com.d4rk.androidtutorials.java.R;
27+
import com.d4rk.androidtutorials.java.ads.managers.NativeAdLoader;
28+
import com.google.android.gms.ads.AdListener;
29+
import com.google.android.gms.ads.AdLoader;
30+
import com.google.android.gms.ads.AdRequest;
31+
import com.google.android.gms.ads.nativead.MediaView;
32+
import com.google.android.gms.ads.nativead.NativeAd;
33+
import com.google.android.gms.ads.nativead.NativeAd.OnNativeAdLoadedListener;
34+
import com.google.android.gms.ads.nativead.NativeAdView;
35+
36+
import org.junit.Test;
37+
import org.mockito.MockedConstruction;
38+
import org.mockito.MockedStatic;
39+
40+
import java.lang.reflect.Method;
41+
import java.util.List;
42+
import java.util.concurrent.atomic.AtomicReference;
43+
44+
/**
45+
* Tests for {@link NativeAdLoader}.
46+
*/
47+
public class NativeAdLoaderTest {
48+
49+
@Test
50+
public void load_whenNativeAdLoaded_populatesContainerAndLoadsAd() throws Exception {
51+
Context context = mock(Context.class);
52+
when(context.getString(R.string.native_ad_banner_unit_id)).thenReturn("unit-id");
53+
when(context.getString(R.string.ad)).thenReturn("Ad");
54+
55+
ViewGroup container = mock(ViewGroup.class);
56+
when(container.getPaddingLeft()).thenReturn(4);
57+
when(container.getPaddingTop()).thenReturn(5);
58+
when(container.getPaddingRight()).thenReturn(6);
59+
when(container.getPaddingBottom()).thenReturn(7);
60+
61+
LayoutInflater inflater = mock(LayoutInflater.class);
62+
NativeAdView adView = mock(NativeAdView.class);
63+
when(adView.getContext()).thenReturn(context);
64+
when(inflater.inflate(eq(R.layout.ad_home_banner_large), eq(container), eq(false))).thenReturn(adView);
65+
66+
MediaView mediaView = mock(MediaView.class);
67+
TextView headlineView = mock(TextView.class);
68+
TextView bodyView = mock(TextView.class);
69+
Button callToActionView = mock(Button.class);
70+
ImageView iconView = mock(ImageView.class);
71+
TextView attributionView = mock(TextView.class);
72+
73+
when(adView.findViewById(R.id.ad_media)).thenReturn(mediaView);
74+
when(adView.findViewById(R.id.ad_headline)).thenReturn(headlineView);
75+
when(adView.findViewById(R.id.ad_body)).thenReturn(bodyView);
76+
when(adView.findViewById(R.id.ad_call_to_action)).thenReturn(callToActionView);
77+
when(adView.findViewById(R.id.ad_app_icon)).thenReturn(iconView);
78+
when(adView.findViewById(R.id.ad_attribution)).thenReturn(attributionView);
79+
80+
NativeAd nativeAd = mock(NativeAd.class);
81+
when(nativeAd.getHeadline()).thenReturn("Headline");
82+
when(nativeAd.getBody()).thenReturn("Body");
83+
when(nativeAd.getCallToAction()).thenReturn("Install");
84+
when(nativeAd.getAdvertiser()).thenReturn("Advertiser");
85+
86+
NativeAd.Image iconAsset = mock(NativeAd.Image.class);
87+
Drawable iconDrawable = mock(Drawable.class);
88+
when(iconAsset.getDrawable()).thenReturn(iconDrawable);
89+
when(nativeAd.getIcon()).thenReturn(iconAsset);
90+
91+
NativeAd.MediaContent mediaContent = mock(NativeAd.MediaContent.class);
92+
when(nativeAd.getMediaContent()).thenReturn(mediaContent);
93+
94+
AdRequest adRequest = mock(AdRequest.class);
95+
AdListener listener = mock(AdListener.class);
96+
AdLoader adLoader = mock(AdLoader.class);
97+
98+
AtomicReference<OnNativeAdLoadedListener> adLoadedListener = new AtomicReference<>();
99+
AtomicReference<List<?>> builderArgs = new AtomicReference<>();
100+
101+
try (MockedStatic<LayoutInflater> inflaterStatic = mockStatic(LayoutInflater.class);
102+
MockedConstruction<AdLoader.Builder> builderConstruction =
103+
mockConstruction(AdLoader.Builder.class, (mockBuilder, constructionContext) -> {
104+
builderArgs.set(constructionContext.arguments());
105+
doAnswer(invocation -> {
106+
adLoadedListener.set(invocation.getArgument(0));
107+
return mockBuilder;
108+
}).when(mockBuilder).forNativeAd(any(OnNativeAdLoadedListener.class));
109+
when(mockBuilder.withAdListener(any(AdListener.class))).thenReturn(mockBuilder);
110+
when(mockBuilder.build()).thenReturn(adLoader);
111+
})) {
112+
113+
inflaterStatic.when(() -> LayoutInflater.from(context)).thenReturn(inflater);
114+
115+
NativeAdLoader.load(context, container, R.layout.ad_home_banner_large, adRequest, listener);
116+
117+
verify(adLoader, times(1)).loadAd(adRequest);
118+
119+
OnNativeAdLoadedListener capturedListener = adLoadedListener.get();
120+
assertNotNull(capturedListener);
121+
capturedListener.onNativeAdLoaded(nativeAd);
122+
123+
AdLoader.Builder builderMock = builderConstruction.constructed().get(0);
124+
verify(builderMock, times(1)).forNativeAd(any(OnNativeAdLoadedListener.class));
125+
verify(builderMock, times(1)).withAdListener(listener);
126+
verify(builderMock, times(1)).build();
127+
128+
verify(container, times(1)).removeAllViews();
129+
verify(container, times(1)).addView(adView);
130+
verify(container, times(1)).requestLayout();
131+
verify(container, times(1)).setPadding(0, 0, 0, 0);
132+
133+
verify(adView, times(1)).setLayoutParams(any(ViewGroup.LayoutParams.class));
134+
verify(adView, times(1)).setPadding(4, 5, 6, 7);
135+
verify(adView, times(1)).setMediaView(mediaView);
136+
verify(adView, times(1)).setHeadlineView(headlineView);
137+
verify(adView, times(1)).setBodyView(bodyView);
138+
verify(adView, times(1)).setCallToActionView(callToActionView);
139+
verify(adView, times(1)).setIconView(iconView);
140+
verify(adView, times(1)).setAdvertiserView(attributionView);
141+
142+
verify(headlineView, times(1)).setText("Headline");
143+
verify(bodyView, times(1)).setVisibility(View.VISIBLE);
144+
verify(bodyView, times(1)).setText("Body");
145+
verify(callToActionView, times(1)).setVisibility(View.VISIBLE);
146+
verify(callToActionView, times(1)).setText("Install");
147+
verify(attributionView, times(1)).setText("Ad Advertiser");
148+
verify(iconView, times(1)).setVisibility(View.VISIBLE);
149+
verify(iconView, times(1)).setImageDrawable(iconDrawable);
150+
verify(mediaView, times(1)).setVisibility(View.VISIBLE);
151+
verify(mediaView, times(1)).setMediaContent(mediaContent);
152+
verify(adView, times(1)).setNativeAd(nativeAd);
153+
}
154+
155+
assertNotNull(builderArgs.get());
156+
assertEquals(context, builderArgs.get().get(0));
157+
assertEquals("unit-id", builderArgs.get().get(1));
158+
}
159+
160+
@Test
161+
public void populateNativeAdView_handlesMissingOptionalAssets() throws Exception {
162+
NativeAd nativeAd = mock(NativeAd.class);
163+
when(nativeAd.getHeadline()).thenReturn("Headline");
164+
when(nativeAd.getBody()).thenReturn(null);
165+
when(nativeAd.getCallToAction()).thenReturn(null);
166+
when(nativeAd.getAdvertiser()).thenReturn(null);
167+
when(nativeAd.getIcon()).thenReturn(null);
168+
when(nativeAd.getMediaContent()).thenReturn(null);
169+
170+
NativeAdView adView = mock(NativeAdView.class);
171+
Context context = mock(Context.class);
172+
when(adView.getContext()).thenReturn(context);
173+
when(context.getString(R.string.ad)).thenReturn("Ad");
174+
175+
MediaView mediaView = mock(MediaView.class);
176+
TextView headlineView = mock(TextView.class);
177+
TextView bodyView = mock(TextView.class);
178+
Button callToActionView = mock(Button.class);
179+
ImageView iconView = mock(ImageView.class);
180+
TextView attributionView = mock(TextView.class);
181+
182+
when(adView.findViewById(R.id.ad_media)).thenReturn(mediaView);
183+
when(adView.findViewById(R.id.ad_headline)).thenReturn(headlineView);
184+
when(adView.findViewById(R.id.ad_body)).thenReturn(bodyView);
185+
when(adView.findViewById(R.id.ad_call_to_action)).thenReturn(callToActionView);
186+
when(adView.findViewById(R.id.ad_app_icon)).thenReturn(iconView);
187+
when(adView.findViewById(R.id.ad_attribution)).thenReturn(attributionView);
188+
189+
invokePopulateNativeAdView(nativeAd, adView);
190+
191+
verify(adView, times(1)).setMediaView(mediaView);
192+
verify(adView, times(1)).setHeadlineView(headlineView);
193+
verify(adView, times(1)).setBodyView(bodyView);
194+
verify(adView, times(1)).setCallToActionView(callToActionView);
195+
verify(adView, times(1)).setIconView(iconView);
196+
verify(adView, times(1)).setAdvertiserView(attributionView);
197+
198+
verify(headlineView, times(1)).setText("Headline");
199+
verify(bodyView, times(1)).setVisibility(View.GONE);
200+
verify(bodyView, never()).setText(anyString());
201+
verify(callToActionView, times(1)).setVisibility(View.GONE);
202+
verify(callToActionView, never()).setText(anyString());
203+
verify(attributionView, times(1)).setText("Ad");
204+
verify(iconView, times(1)).setVisibility(View.GONE);
205+
verify(iconView, never()).setImageDrawable(any(Drawable.class));
206+
verify(mediaView, times(1)).setVisibility(View.GONE);
207+
verify(mediaView, never()).setMediaContent(any());
208+
verify(adView, times(1)).setNativeAd(nativeAd);
209+
}
210+
211+
private static void invokePopulateNativeAdView(NativeAd nativeAd, NativeAdView adView) throws Exception {
212+
Method method = NativeAdLoader.class.getDeclaredMethod("populateNativeAdView", NativeAd.class, NativeAdView.class);
213+
method.setAccessible(true);
214+
method.invoke(null, nativeAd, adView);
215+
}
216+
}

0 commit comments

Comments
 (0)