Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Refactor AdUtils tests to use fake ad views #227

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

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.d4rk.androidtutorials.java.ads;

import static org.mockito.Mockito.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;

import android.content.Context;
import android.test.mock.MockContext;
import android.view.View;

import com.d4rk.androidtutorials.java.ads.views.NativeAdBannerView;
Expand All @@ -21,6 +25,8 @@
*/
public class AdUtilsTest {

private final TestContext context = new TestContext();

@Before
public void setUp() throws Exception {
// Reset the initialized flag before each test
Expand All @@ -31,9 +37,6 @@ public void setUp() throws Exception {

@Test
public void initialize_callsMobileAdsInitializeOnlyOnce() {
Context context = mock(Context.class);
when(context.getApplicationContext()).thenReturn(context);

try (MockedStatic<MobileAds> mobileAds = mockStatic(MobileAds.class)) {
AdUtils.initialize(context);
AdUtils.initialize(context);
Expand All @@ -44,44 +47,84 @@ public void initialize_callsMobileAdsInitializeOnlyOnce() {

@Test
public void loadBanner_withAdView_loadsAd() {
Context context = mock(Context.class);
when(context.getApplicationContext()).thenReturn(context);
AdView adView = mock(AdView.class);
when(adView.getContext()).thenReturn(context);
FakeAdView adView = new FakeAdView(context);

try (MockedStatic<MobileAds> mobileAds = mockStatic(MobileAds.class)) {
AdUtils.loadBanner(adView);
mobileAds.verify(() -> MobileAds.initialize(context));
}

verify(adView, times(1)).loadAd(any(AdRequest.class));
assertTrue(adView.isLoadAdCalled());
assertNotNull(adView.getLastRequest());
}

@Test
public void loadBanner_withNativeAdBannerView_loadsAd() {
Context context = mock(Context.class);
when(context.getApplicationContext()).thenReturn(context);
NativeAdBannerView nativeView = mock(NativeAdBannerView.class);
when(nativeView.getContext()).thenReturn(context);
FakeNativeAdBannerView nativeView = new FakeNativeAdBannerView(context);

try (MockedStatic<MobileAds> mobileAds = mockStatic(MobileAds.class)) {
AdUtils.loadBanner(nativeView);
mobileAds.verify(() -> MobileAds.initialize(context));
}

verify(nativeView, times(1)).loadAd();
assertTrue(nativeView.isLoadAdCalled());
}

@Test
public void loadBanner_withOtherView_doesNothing() {
Context context = mock(Context.class);
when(context.getApplicationContext()).thenReturn(context);
View view = mock(View.class);
when(view.getContext()).thenReturn(context);
View view = new View(context);

try (MockedStatic<MobileAds> mobileAds = mockStatic(MobileAds.class)) {
AdUtils.loadBanner(view);
mobileAds.verifyNoInteractions();
}

}

private static final class TestContext extends MockContext {
@Override
public Context getApplicationContext() {
return this;
}
}

private static final class FakeAdView extends AdView {
private boolean loadAdCalled;
private AdRequest lastRequest;

FakeAdView(Context context) {
super(context);
Comment on lines +91 to +96
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Avoid instantiating Android views in plain unit tests

The new FakeAdView/FakeNativeAdBannerView subclasses call the real AdView and NativeAdBannerView constructors. Those classes depend on Android UI and Google Play Services state (e.g., LayoutTransition, thread loopers) and cannot be instantiated in app/src/test JVM tests without Robolectric or instrumentation. The previous Mockito approach avoided touching framework code, but now the test suite will throw RuntimeException("Stub!") or similar before it can verify behavior. Consider keeping mocks or moving these tests to an Android-aware test environment.

Useful? React with 👍 / 👎.

}

@Override
public void loadAd(AdRequest adRequest) {
loadAdCalled = true;
lastRequest = adRequest;
}

boolean isLoadAdCalled() {
return loadAdCalled;
}

AdRequest getLastRequest() {
return lastRequest;
}
}

private static final class FakeNativeAdBannerView extends NativeAdBannerView {
private boolean loadAdCalled;

FakeNativeAdBannerView(Context context) {
super(context);
}

@Override
public void loadAd() {
loadAdCalled = true;
}

boolean isLoadAdCalled() {
return loadAdCalled;
}
}
}
Loading

AltStyle によって変換されたページ (->オリジナル) /