diff --git a/app/build.gradle b/app/build.gradle index 8fc180bc..be958d73 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -107,4 +107,5 @@ dependencies { testImplementation libs.androidx.core.testing testImplementation libs.mockito.core testImplementation libs.mockito.inline + testImplementation libs.robolectric } \ No newline at end of file diff --git a/app/src/test/java/com/d4rk/androidtutorials/java/ads/views/NativeAdBannerViewTest.java b/app/src/test/java/com/d4rk/androidtutorials/java/ads/views/NativeAdBannerViewTest.java new file mode 100644 index 00000000..4e0fc3d7 --- /dev/null +++ b/app/src/test/java/com/d4rk/androidtutorials/java/ads/views/NativeAdBannerViewTest.java @@ -0,0 +1,130 @@ +package com.d4rk.androidtutorials.java.ads.views; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; + +import android.content.Context; +import android.util.AttributeSet; + +import com.d4rk.androidtutorials.java.R; +import com.d4rk.androidtutorials.java.ads.managers.NativeAdLoader; +import com.google.android.gms.ads.AdListener; +import com.google.android.gms.ads.AdRequest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class NativeAdBannerViewTest { + + private Context context; + + @Before + public void setUp() { + context = RuntimeEnvironment.getApplication(); + } + + @Test + public void loadAd_withoutArguments_delegatesToNativeAdLoader() { + NativeAdBannerView view = new NativeAdBannerView(context); + + try (MockedStatic loaderMock = Mockito.mockStatic(NativeAdLoader.class)) { + view.loadAd(); + + loaderMock.verify(() -> NativeAdLoader.load( + eq(context), + eq(view), + eq(R.layout.ad_home_banner_large), + any(AdRequest.class), + isNull() + )); + loaderMock.verifyNoMoreInteractions(); + } + } + + @Test + public void loadAd_withListener_delegatesToNativeAdLoader() { + NativeAdBannerView view = new NativeAdBannerView(context); + AdListener listener = new AdListener() { }; + + try (MockedStatic loaderMock = Mockito.mockStatic(NativeAdLoader.class)) { + view.loadAd(listener); + + loaderMock.verify(() -> NativeAdLoader.load( + eq(context), + eq(view), + eq(R.layout.ad_home_banner_large), + any(AdRequest.class), + eq(listener) + )); + loaderMock.verifyNoMoreInteractions(); + } + } + + @Test + public void loadAd_withRequest_delegatesToNativeAdLoader() { + NativeAdBannerView view = new NativeAdBannerView(context); + AdRequest request = new AdRequest.Builder().build(); + + try (MockedStatic loaderMock = Mockito.mockStatic(NativeAdLoader.class)) { + view.loadAd(request); + + loaderMock.verify(() -> NativeAdLoader.load( + eq(context), + eq(view), + eq(R.layout.ad_home_banner_large), + eq(request), + isNull() + )); + loaderMock.verifyNoMoreInteractions(); + } + } + + @Test + public void loadAd_withRequestAndListener_delegatesToNativeAdLoader() { + NativeAdBannerView view = new NativeAdBannerView(context); + AdRequest request = new AdRequest.Builder().build(); + AdListener listener = new AdListener() { }; + + try (MockedStatic loaderMock = Mockito.mockStatic(NativeAdLoader.class)) { + view.loadAd(request, listener); + + loaderMock.verify(() -> NativeAdLoader.load( + eq(context), + eq(view), + eq(R.layout.ad_home_banner_large), + eq(request), + eq(listener) + )); + loaderMock.verifyNoMoreInteractions(); + } + } + + @Test + public void constructor_withNativeAdLayoutAttribute_setsLayoutResource() { + AttributeSet attrs = Robolectric.buildAttributeSet() + .addAttribute(R.attr.nativeAdLayout, "@layout/ad_home_banner_small") + .build(); + NativeAdBannerView view = new NativeAdBannerView(context, attrs); + + try (MockedStatic loaderMock = Mockito.mockStatic(NativeAdLoader.class)) { + view.loadAd(); + + loaderMock.verify(() -> NativeAdLoader.load( + eq(context), + eq(view), + eq(R.layout.ad_home_banner_small), + any(AdRequest.class), + isNull() + )); + loaderMock.verifyNoMoreInteractions(); + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f62cc9df..e86897e6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -30,6 +30,7 @@ hilt = "2.57.1" room = "2.8.0" glide = "5.0.4" retrofit = "3.0.0" +robolectric = "4.12.2" [libraries] aboutlibraries = { module = "com.mikepenz:aboutlibraries", version.ref = "aboutlibraries" } @@ -73,3 +74,4 @@ glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" } glide-compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glide" } retrofit2 = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } retrofit2-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" } +robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" }