From 774c65012fbff8c6cdbcdba45bc0d68a0e5dde13 Mon Sep 17 00:00:00 2001 From: Andreas Mager Date: Wed, 29 Apr 2020 16:38:24 +0200 Subject: [PATCH] Extension system added for junit 5+ --- build.gradle | 1 + daggermock/build.gradle | 1 + .../daggermock/DaggerMockExtension.java | 41 ++++++++++++ .../daggermock/DaggerMockModules.java | 12 ++++ .../daggermock/DaggerMockTest.java | 13 ++++ daggermockTests/build.gradle | 12 +++- .../InjectFromComponentExtensionTest.java | 62 +++++++++++++++++++ 7 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockExtension.java create mode 100644 daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockModules.java create mode 100644 daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockTest.java create mode 100644 daggermockTests/src/test/java/it/cosenonjaviste/daggermock/injectfromcomponent/InjectFromComponentExtensionTest.java diff --git a/build.gradle b/build.gradle index 976c274..3de871b 100644 --- a/build.gradle +++ b/build.gradle @@ -34,6 +34,7 @@ buildscript { allprojects { repositories { jcenter() + mavenCentral() maven { url 'https://jitpack.io' } google() } diff --git a/daggermock/build.gradle b/daggermock/build.gradle index 6ebc98a..903571e 100644 --- a/daggermock/build.gradle +++ b/daggermock/build.gradle @@ -26,6 +26,7 @@ targetCompatibility = 1.8 dependencies { compileOnly "org.mockito:mockito-core:$MOCKITO_VERSION" compileOnly 'junit:junit:4.12' + compileOnly 'org.junit.jupiter:junit-jupiter:5.6.1' compileOnly "com.google.dagger:dagger:$DAGGER_VERSION" } diff --git a/daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockExtension.java b/daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockExtension.java new file mode 100644 index 0000000..30cebee --- /dev/null +++ b/daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockExtension.java @@ -0,0 +1,41 @@ +package it.cosenonjaviste.daggermock; + +import java.lang.reflect.Field; +import java.util.*; + +import org.junit.jupiter.api.extension.*; +import org.junit.platform.commons.support.AnnotationSupport; +import org.junit.platform.commons.util.ReflectionUtils; + +public class DaggerMockExtension implements BeforeEachCallback { + + @SuppressWarnings("unchecked") + @Override + public void beforeEach(ExtensionContext context) throws Exception { + context.getTestInstance().ifPresent(testInstance -> { + DaggerMockTest annotation = testInstance.getClass().getDeclaredAnnotation(DaggerMockTest.class); + + ArrayList modules = new ArrayList<>(); + + List fields = AnnotationSupport.findAnnotatedFields(testInstance.getClass(), + DaggerMockModules.class); + + for (Field field : fields) { + try { + modules.addAll((Collection) ReflectionUtils.tryToReadFieldValue(field, testInstance).get()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + //TODO Extract helper class from Rule to remove junit 4 dependency + DaggerMockRule rule = new DaggerMockRule<>(annotation.value(), modules.toArray()); + + try { + rule.initMocks(testInstance); + } catch (Throwable e) { + e.printStackTrace(); + } + }); + } +} diff --git a/daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockModules.java b/daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockModules.java new file mode 100644 index 0000000..982715d --- /dev/null +++ b/daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockModules.java @@ -0,0 +1,12 @@ +package it.cosenonjaviste.daggermock; + +import java.lang.annotation.*; + +import org.junit.jupiter.api.extension.ExtendWith; + +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(DaggerMockExtension.class) +public @interface DaggerMockModules { + +} diff --git a/daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockTest.java b/daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockTest.java new file mode 100644 index 0000000..579966a --- /dev/null +++ b/daggermock/src/main/java/it/cosenonjaviste/daggermock/DaggerMockTest.java @@ -0,0 +1,13 @@ +package it.cosenonjaviste.daggermock; + +import java.lang.annotation.*; + +import org.junit.jupiter.api.extension.ExtendWith; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(DaggerMockExtension.class) +public @interface DaggerMockTest { + + Class value(); +} diff --git a/daggermockTests/build.gradle b/daggermockTests/build.gradle index 65a7d2d..e9953be 100644 --- a/daggermockTests/build.gradle +++ b/daggermockTests/build.gradle @@ -26,13 +26,23 @@ dependencies { testImplementation project(':daggermock') testImplementation "org.mockito:mockito-core:$MOCKITO_VERSION" - testImplementation 'junit:junit:4.12' + testImplementation "org.junit.jupiter:junit-jupiter:5.6.1" + testImplementation 'org.junit.vintage:junit-vintage-engine:5.6.1' + testCompile("org.junit.platform:junit-platform-commons:1.6.1") + testCompile 'org.junit.platform:junit-platform-engine:1.6.1' testImplementation "com.google.dagger:dagger:$DAGGER_VERSION" testImplementation 'org.glassfish:javax.annotation:10.0-b28' testAnnotationProcessor "com.google.dagger:dagger-compiler:$DAGGER_VERSION" testImplementation 'org.assertj:assertj-core:2.5.0' } +test { + useJUnitPlatform() + testLogging { + events "passed", "skipped", "failed" + } +} + task codeCoverageReport(type: JacocoReport) { executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec") diff --git a/daggermockTests/src/test/java/it/cosenonjaviste/daggermock/injectfromcomponent/InjectFromComponentExtensionTest.java b/daggermockTests/src/test/java/it/cosenonjaviste/daggermock/injectfromcomponent/InjectFromComponentExtensionTest.java new file mode 100644 index 0000000..6c49c08 --- /dev/null +++ b/daggermockTests/src/test/java/it/cosenonjaviste/daggermock/injectfromcomponent/InjectFromComponentExtensionTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2016 Fabio Collini. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package it.cosenonjaviste.daggermock.injectfromcomponent; + +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; +import java.util.Collection; +import java.util.Collections; + +import org.junit.jupiter.api.extension.ExtendWith; + +import dagger.Module; +import dagger.Provides; +import dagger.Component; +import it.cosenonjaviste.daggermock.DaggerMockExtension; +import it.cosenonjaviste.daggermock.DaggerMockTest; +import it.cosenonjaviste.daggermock.DaggerMockModules; +import it.cosenonjaviste.daggermock.InjectFromComponent; + +@ExtendWith(DaggerMockExtension.class) +@DaggerMockTest(InjectFromComponentExtensionTest.MyComponent.class) +public class InjectFromComponentExtensionTest { + + @DaggerMockModules + Collection list = Collections.singleton(new MyModule()); + + String s1 = "test1"; + + @InjectFromComponent MainService mainService; + + @Test + public void testInjectFromComponent() { + assertThat(mainService).isNotNull(); + assertThat(mainService.get()).isEqualTo("test1"); + } + + @Module + public static class MyModule { + @Provides public String provideS1() { + return "s1"; + } + } + + @Component(modules = MyModule.class) + public interface MyComponent { + MainService mainService(); + } +}