#432 Create custom dependency injector
This commit is contained in:
@@ -18,10 +18,10 @@ import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
@@ -41,6 +41,7 @@ import static org.mockito.Mockito.verify;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CommandServiceTest {
|
||||
|
||||
@InjectMocks
|
||||
private CommandService commandService;
|
||||
@Mock
|
||||
private AuthMe authMe;
|
||||
@@ -67,12 +68,6 @@ public class CommandServiceTest {
|
||||
@Mock
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Before
|
||||
public void setUpService() {
|
||||
commandService = new CommandService(authMe, commandMapper, helpProvider, messages, passwordSecurity,
|
||||
permissionsManager, settings, pluginHooks, spawnLoader, antiBot, validationService, bukkitService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSendMessage() {
|
||||
// given
|
||||
|
||||
@@ -6,6 +6,8 @@ import fr.xephi.authme.command.FoundResultStatus;
|
||||
import fr.xephi.authme.command.TestCommandsUtil;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.permission.PlayerPermission;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.junit.Before;
|
||||
@@ -52,7 +54,9 @@ public class HelpProviderTest {
|
||||
@Before
|
||||
public void setUpHelpProvider() {
|
||||
permissionsManager = mock(PermissionsManager.class);
|
||||
helpProvider = new HelpProvider(permissionsManager, HELP_HEADER);
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(PluginSettings.HELP_HEADER)).willReturn(HELP_HEADER);
|
||||
helpProvider = new HelpProvider(permissionsManager, settings);
|
||||
sender = mock(CommandSender.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
package fr.xephi.authme.initialization;
|
||||
|
||||
import fr.xephi.authme.initialization.samples.BadFieldInjection;
|
||||
import fr.xephi.authme.initialization.samples.BetaManager;
|
||||
import fr.xephi.authme.initialization.samples.CircularClasses;
|
||||
import fr.xephi.authme.initialization.samples.ClassWithAbstractDependency;
|
||||
import fr.xephi.authme.initialization.samples.ClassWithAnnotations;
|
||||
import fr.xephi.authme.initialization.samples.Duration;
|
||||
import fr.xephi.authme.initialization.samples.FieldInjectionWithAnnotations;
|
||||
import fr.xephi.authme.initialization.samples.InvalidClass;
|
||||
import fr.xephi.authme.initialization.samples.InvalidPostConstruct;
|
||||
import fr.xephi.authme.initialization.samples.PostConstructTestClass;
|
||||
import fr.xephi.authme.initialization.samples.ProvidedClass;
|
||||
import fr.xephi.authme.initialization.samples.Size;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Test for {@link AuthMeServiceInitializer}.
|
||||
*/
|
||||
public class AuthMeServiceInitializerTest {
|
||||
|
||||
private static final String ALLOWED_PACKAGE = "fr.xephi.authme.initialization";
|
||||
|
||||
private AuthMeServiceInitializer initializer;
|
||||
|
||||
@Before
|
||||
public void setInitializer() {
|
||||
initializer = new AuthMeServiceInitializer(ALLOWED_PACKAGE);
|
||||
initializer.register(new ProvidedClass(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldInitializeElements() {
|
||||
// given / when
|
||||
BetaManager betaManager = initializer.get(BetaManager.class);
|
||||
|
||||
// then
|
||||
assertThat(betaManager, not(nullValue()));
|
||||
for (Object o : betaManager.getDependencies()) {
|
||||
assertThat(o, not(nullValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void shouldThrowForInvalidPackage() {
|
||||
// given / when / then
|
||||
initializer.get(InvalidClass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldPassValueByAnnotation() {
|
||||
// given
|
||||
int size = 12;
|
||||
long duration = -15482L;
|
||||
initializer.provide(Size.class, size);
|
||||
initializer.provide(Duration.class, duration);
|
||||
|
||||
// when
|
||||
ClassWithAnnotations object = initializer.get(ClassWithAnnotations.class);
|
||||
|
||||
// then
|
||||
assertThat(object, not(nullValue()));
|
||||
assertThat(object.getSize(), equalTo(size));
|
||||
assertThat(object.getDuration(), equalTo(duration));
|
||||
// some sample check to make sure we only have one instance of GammaService
|
||||
assertThat(object.getGammaService(), equalTo(initializer.get(BetaManager.class).getDependencies()[1]));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldRecognizeCircularReferences() {
|
||||
// given / when / then
|
||||
initializer.get(CircularClasses.Circular3.class);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldThrowForUnregisteredAnnotation() {
|
||||
// given
|
||||
initializer.provide(Size.class, 4523);
|
||||
|
||||
// when / then
|
||||
initializer.get(ClassWithAnnotations.class);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldThrowForFieldInjectionWithNoDefaultConstructor() {
|
||||
// given / when / then
|
||||
initializer.get(BadFieldInjection.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldInjectFieldsWithAnnotationsProperly() {
|
||||
// given
|
||||
initializer.provide(Size.class, 2809375);
|
||||
initializer.provide(Duration.class, 13095L);
|
||||
|
||||
// when
|
||||
FieldInjectionWithAnnotations result = initializer.get(FieldInjectionWithAnnotations.class);
|
||||
|
||||
// then
|
||||
assertThat(result.getSize(), equalTo(2809375));
|
||||
assertThat(result.getDuration(), equalTo(13095L));
|
||||
assertThat(result.getBetaManager(), not(nullValue()));
|
||||
assertThat(result.getClassWithAnnotations(), not(nullValue()));
|
||||
assertThat(result.getClassWithAnnotations().getGammaService(),
|
||||
equalTo(result.getBetaManager().getDependencies()[1]));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldThrowForAnnotationAsKey() {
|
||||
// given / when / then
|
||||
initializer.get(Size.class);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldThrowForSecondRegistration() {
|
||||
// given / when / then
|
||||
initializer.register(new ProvidedClass(""));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldThrowForSecondAnnotationRegistration() {
|
||||
// given
|
||||
initializer.provide(Size.class, 12);
|
||||
|
||||
// when / then
|
||||
initializer.provide(Size.class, -8);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void shouldThrowForNullValueAssociatedToAnnotation() {
|
||||
// given / when / then
|
||||
initializer.provide(Duration.class, null);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void shouldThrowForRegisterWithNull() {
|
||||
// given / when / then
|
||||
initializer.register(String.class, null);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldThrowForRegisterOfType() {
|
||||
// given / when / then
|
||||
// this most likely means that the second argument was forgotten, so throw an error and force
|
||||
// the API user to use the explicit register(Class.class, String.class) if really, really desired
|
||||
// (Though for such generic types, an annotation would be a lot better)
|
||||
initializer.register(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldExecutePostConstructMethod() {
|
||||
// given
|
||||
initializer.provide(Size.class, 15123);
|
||||
|
||||
// when
|
||||
PostConstructTestClass testClass = initializer.get(PostConstructTestClass.class);
|
||||
|
||||
// then
|
||||
assertThat(testClass.werePostConstructsCalled(), equalTo(true));
|
||||
assertThat(testClass.getBetaManager(), not(nullValue()));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldThrowForInvalidPostConstructMethod() {
|
||||
// given / when / then
|
||||
initializer.get(InvalidPostConstruct.class);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldThrowForAbstractNonRegisteredDependency() {
|
||||
// given / when / then
|
||||
initializer.get(ClassWithAbstractDependency.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldInstantiateWithImplementationOfAbstractDependency() {
|
||||
// given
|
||||
ClassWithAbstractDependency.ConcreteDependency concrete = new ClassWithAbstractDependency.ConcreteDependency();
|
||||
initializer.register(ClassWithAbstractDependency.AbstractDependency.class, concrete);
|
||||
|
||||
// when
|
||||
ClassWithAbstractDependency cwad = initializer.get(ClassWithAbstractDependency.class);
|
||||
|
||||
// then
|
||||
assertThat(cwad.getAbstractDependency() == concrete, equalTo(true));
|
||||
assertThat(cwad.getAlphaService(), not(nullValue()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Sample - class with dependency to ProvidedClass.
|
||||
*/
|
||||
public class AlphaService {
|
||||
|
||||
private ProvidedClass providedClass;
|
||||
|
||||
@Inject
|
||||
AlphaService(ProvidedClass providedClass) {
|
||||
this.providedClass = providedClass;
|
||||
}
|
||||
|
||||
public ProvidedClass getProvidedClass() {
|
||||
return providedClass;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Sample class with invalid field injection (requires default constructor).
|
||||
*/
|
||||
public class BadFieldInjection {
|
||||
|
||||
@Inject
|
||||
private AlphaService alphaService;
|
||||
|
||||
public BadFieldInjection(BetaManager betaManager) {
|
||||
throw new IllegalStateException("Should never be called");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Sample - depends on Provided, alpha and gamma.
|
||||
*/
|
||||
public class BetaManager {
|
||||
|
||||
@Inject
|
||||
private ProvidedClass providedClass;
|
||||
@Inject
|
||||
private GammaService gammaService;
|
||||
@Inject
|
||||
private AlphaService alphaService;
|
||||
|
||||
public Object[] getDependencies() {
|
||||
return new Object[]{providedClass, gammaService, alphaService};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Classes with circular dependencies.
|
||||
*/
|
||||
public class CircularClasses {
|
||||
|
||||
public static final class Circular1 {
|
||||
@Inject
|
||||
public Circular1(AlphaService alphaService, Circular3 circular3) {
|
||||
// --
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Circular2 {
|
||||
@Inject
|
||||
public Circular2(Circular1 circular1) {
|
||||
// --
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Circular3 {
|
||||
@Inject
|
||||
public Circular3(Circular2 circular2, BetaManager betaManager) {
|
||||
// --
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Test with an abstract class declared as dependency.
|
||||
*/
|
||||
public class ClassWithAbstractDependency {
|
||||
|
||||
private final AlphaService alphaService;
|
||||
private final AbstractDependency abstractDependency;
|
||||
|
||||
@Inject
|
||||
public ClassWithAbstractDependency(AlphaService as, AbstractDependency ad) {
|
||||
this.alphaService = as;
|
||||
this.abstractDependency = ad;
|
||||
}
|
||||
|
||||
public AlphaService getAlphaService() {
|
||||
return alphaService;
|
||||
}
|
||||
|
||||
public AbstractDependency getAbstractDependency() {
|
||||
return abstractDependency;
|
||||
}
|
||||
|
||||
public static abstract class AbstractDependency {
|
||||
}
|
||||
|
||||
public static final class ConcreteDependency extends AbstractDependency {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class ClassWithAnnotations {
|
||||
|
||||
private int size;
|
||||
private GammaService gammaService;
|
||||
private long duration;
|
||||
|
||||
@Inject
|
||||
ClassWithAnnotations(@Size int size, GammaService gammaService, @Duration long duration) {
|
||||
this.size = size;
|
||||
this.gammaService = gammaService;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public GammaService getGammaService() {
|
||||
return gammaService;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Sample annotation.
|
||||
*/
|
||||
@Target({ElementType.PARAMETER, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Duration {
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Sample - field injection, including custom annotations.
|
||||
*/
|
||||
public class FieldInjectionWithAnnotations {
|
||||
|
||||
@Inject
|
||||
private BetaManager betaManager;
|
||||
@Inject
|
||||
@Size
|
||||
private int size;
|
||||
@Duration
|
||||
@Inject
|
||||
private long duration;
|
||||
@Inject
|
||||
protected ClassWithAnnotations classWithAnnotations;
|
||||
|
||||
FieldInjectionWithAnnotations() {
|
||||
}
|
||||
|
||||
public BetaManager getBetaManager() {
|
||||
return betaManager;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public ClassWithAnnotations getClassWithAnnotations() {
|
||||
return classWithAnnotations;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Sample - class dependent on alpha and provided.
|
||||
*/
|
||||
public class GammaService {
|
||||
|
||||
private AlphaService alphaService;
|
||||
|
||||
@Inject
|
||||
GammaService(AlphaService alphaService) {
|
||||
this.alphaService = alphaService;
|
||||
}
|
||||
|
||||
public AlphaService getAlphaService() {
|
||||
return alphaService;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Sample - invalid class, since Integer parameter type is outside of the allowed package and not annotated.
|
||||
*/
|
||||
public class InvalidClass {
|
||||
|
||||
@Inject
|
||||
public InvalidClass(AlphaService alphaService, Integer i) {
|
||||
throw new IllegalStateException("Should never be called");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Class with invalid @PostConstruct method.
|
||||
*/
|
||||
public class InvalidPostConstruct {
|
||||
|
||||
@Inject
|
||||
private AlphaService alphaService;
|
||||
@Inject
|
||||
private ProvidedClass providedClass;
|
||||
|
||||
@PostConstruct
|
||||
public void invalidPostConstr(BetaManager betaManager) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Sample class for testing the execution of the @PostConstruct method.
|
||||
*/
|
||||
public class PostConstructTestClass {
|
||||
|
||||
@Inject
|
||||
@Size
|
||||
private int size;
|
||||
@Inject
|
||||
private BetaManager betaManager;
|
||||
private boolean wasPostConstructCalled = false;
|
||||
private boolean wasSecondPostConstructCalled = false;
|
||||
|
||||
@PostConstruct
|
||||
protected void setFieldToTrue() {
|
||||
wasPostConstructCalled = true;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public int otherPostConstructMethod() {
|
||||
wasSecondPostConstructCalled = true;
|
||||
return 42;
|
||||
}
|
||||
|
||||
public boolean werePostConstructsCalled() {
|
||||
return wasPostConstructCalled && wasSecondPostConstructCalled;
|
||||
}
|
||||
|
||||
public BetaManager getBetaManager() {
|
||||
return betaManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Sample - class that is always provided to the initializer beforehand.
|
||||
*/
|
||||
public class ProvidedClass {
|
||||
|
||||
@Inject
|
||||
public ProvidedClass() {
|
||||
throw new IllegalStateException("Should never be called (tests always provide this class)");
|
||||
}
|
||||
|
||||
public ProvidedClass(String manualConstructor) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package fr.xephi.authme.initialization.samples;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Sample annotation.
|
||||
*/
|
||||
@Target({ElementType.PARAMETER, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Size {
|
||||
}
|
||||
@@ -13,9 +13,9 @@ import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import fr.xephi.authme.util.ValidationService;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ProcessServiceTest {
|
||||
|
||||
@InjectMocks
|
||||
private ProcessService processService;
|
||||
@Mock
|
||||
private ValidationService validationService;
|
||||
@@ -51,12 +52,6 @@ public class ProcessServiceTest {
|
||||
@Mock
|
||||
private BukkitService bukkitService;
|
||||
|
||||
@Before
|
||||
public void setUpService() {
|
||||
processService = new ProcessService(settings, messages, authMe, dataSource, passwordSecurity,
|
||||
pluginHooks, spawnLoader, validationService, bukkitService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetProperty() {
|
||||
// given
|
||||
|
||||
Reference in New Issue
Block a user