Skip to content
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

Adding tests for DI #195

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
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
34 changes: 33 additions & 1 deletion di/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,26 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

<!-- testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand All @@ -45,9 +62,24 @@
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<dependencies>

</dependencies>
<configuration>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
<threadCount>1</threadCount>
<systemPropertyVariables>

</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>

</project>
23 changes: 4 additions & 19 deletions di/src/main/java/org/correomqtt/di/SoyDi.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
package org.correomqtt.di;

import io.github.classgraph.AnnotationClassRef;
import io.github.classgraph.AnnotationInfo;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo;
import io.github.classgraph.ScanResult;
import io.github.classgraph.*;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.lang.reflect.*;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
Expand Down Expand Up @@ -178,7 +163,7 @@ private static synchronized <T> T inject(Class<T> clazz, List<Class<?>> chain) {
}
try {
final T instance;
if (Factory.class.isAssignableFrom(clazz) || clazz.getName().startsWith("org.correomqtt.di")) {
if (Factory.class.isAssignableFrom(clazz) || clazz.getName().startsWith("org.correomqtt.di.")) {
instance = getNewInstance(clazz, chain, beanInfo);
} else {
instance = getInstanceViaFactory(clazz);
Expand Down
83 changes: 83 additions & 0 deletions ditest/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>


<name>CorreoMQTT DI Testing</name>

<parent>
<groupId>org.correomqtt</groupId>
<artifactId>correomqtt</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>ditest</artifactId>

<dependencies>
<!-- testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.correomqtt</groupId>
<artifactId>di</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</annotationProcessorPath>
<annotationProcessorPath>
<groupId>org.correomqtt</groupId>
<artifactId>di</artifactId>
<version>${project.version}</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<dependencies>

</dependencies>
<configuration>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
<threadCount>1</threadCount>
<systemPropertyVariables>

</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
5 changes: 5 additions & 0 deletions ditest/src/test/java/org/correomqtt/.info
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# DO NOT RENAME THIS PACKAGE

There is a check in the Soy injection which checks whether the package name has `com.correomqtt.di.`.
This is due to direct injection of internal classes, however, external classes are injected via a factory. Thus,
the test package di tests the direct instantiation and ditest tests the factory instantiation.
182 changes: 182 additions & 0 deletions ditest/src/test/java/org/correomqtt/di/DirectBeanInjectionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package org.correomqtt.di;

import org.correomqtt.di.complexbeans.ComplexOven;
import org.correomqtt.di.complexbeans.SingletonOven;
import org.correomqtt.di.simplebeans.DirectVehicle;
import org.correomqtt.di.simplebeans.SingletonVehicle;
import org.correomqtt.ditest.simplebeans.FactoryVehicle;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class DirectBeanInjectionTest {

@BeforeEach
public void setUp() {
SoyDi.scan("org.correomqtt.di");
SoyDi.scan("org.correomqtt.ditest");

// reset, soydi has currently no way to remove beans
var vehicle = SoyDi.inject(SingletonVehicle.class);
vehicle.setSpeed(100);
}

@Test
void injectDiBean_injectBean_shouldInject() {

// arrange

// act
var bean = SoyDi.inject(DirectVehicle.class);

// assert
assertNotNull(bean);
assertNotNull(bean.getMotor());
assertEquals(100, bean.getMotor().getSpeed());
}

@Test
void injectDiBean_callMethod_shouldUpdate() {

// arrange
var bean = SoyDi.inject(DirectVehicle.class);

// act
int speedBefore = bean.getMotor().getSpeed();
bean.getMotor().setSpeed(130);
int speedAfter = bean.getMotor().getSpeed();

// assert
assertNotNull(bean);
assertEquals(100, speedBefore);
assertEquals(130, speedAfter);
}

@Test
void injectDiBean_unscannedBean_shouldThrow() {

// arrange

// act
var expected = assertThrows(SoyDiException.class, () -> SoyDi.inject(Math.class));

// assert
assertNotNull(expected);
assertEquals("Can not inject class java.lang.Math, cause it was not scanned. ", expected.getMessage());
}

@Test
void injectDiBean_twice_shouldBeDifferent() {

// arrange
var bean1 = SoyDi.inject(FactoryVehicle.class);
var bean2 = SoyDi.inject(FactoryVehicle.class);

// act
var speedBefore1 = bean1.getMotor().getSpeed();
var speedBefore2 = bean2.getMotor().getSpeed();

bean1.getMotor().setSpeed(130);
bean2.getMotor().setSpeed(140);

var speedAfter1 = bean1.getMotor().getSpeed();
var speedAfter2 = bean2.getMotor().getSpeed();

// assert
assertNotNull(bean1);
assertInstanceOf(FactoryVehicle.class, bean1);

assertNotNull(bean2);
assertInstanceOf(FactoryVehicle.class, bean2);

assertEquals(100, speedBefore1);
assertEquals(100, speedBefore2);
assertEquals(130, speedAfter1);
assertEquals(140, speedAfter2);
assertNotEquals(bean1, bean2);
}

// complex direct bean injection
@Test
void injectComplexBean_circularReferences_shouldNotInject() {

// arrange

// act
var expected = assertThrows(SoyDiException.class, () -> SoyDi.inject(ComplexOven.class));

// assert
assertNotNull(expected);
// constructor injection does not allow for circular dependencies
assertTrue(expected.getMessage().contains("Detected dependency cycle: "));
}

@Test
void injectComplexSingletonBean_circularReferences_shouldNotInject() {

// arrange

// act
var expected = assertThrows(SoyDiException.class, () -> SoyDi.inject(SingletonOven.class));

// assert
assertNotNull(expected);
// constructor injection does not allow for circular dependencies
assertTrue(expected.getMessage().contains("Detected dependency cycle: "));
}

// singleton bean tests
@Test
void injectSingletonBean_injectBean_shouldInject() {

// arrange

// act
var bean = SoyDi.inject(SingletonVehicle.class);

// assert
assertNotNull(bean);
assertNotNull(bean.getMotor());
assertEquals(100, bean.getMotor().getSpeed());
}

@Test
void injectSingletonBean_callMethod_shouldUpdate() {

// arrange
var bean = SoyDi.inject(SingletonVehicle.class);

// act
int speedBefore = bean.getMotor().getSpeed();
bean.getMotor().setSpeed(130);
int speedAfter = bean.getMotor().getSpeed();

// assert
assertNotNull(bean);
assertEquals(100, speedBefore);
assertEquals(130, speedAfter);
}

@Test
void injectSingletonBean_twice_shouldBeSame() {

// arrange
var bean1 = SoyDi.inject(SingletonVehicle.class);
var bean2 = SoyDi.inject(SingletonVehicle.class);

// act
int speedBefore = bean1.getMotor().getSpeed();
bean1.getMotor().setSpeed(130);
bean2.getMotor().setSpeed(140);
int speedAfter = bean1.getMotor().getSpeed();

// assert
assertNotNull(bean1);
assertNotNull(bean2);
assertEquals(bean1, bean2);
assertEquals(bean1.getMotor(), bean2.getMotor());
assertEquals(100, speedBefore);
assertEquals(140, speedAfter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.correomqtt.di.complexbeans;

import lombok.Getter;
import lombok.Setter;
import org.correomqtt.di.DefaultBean;
import org.correomqtt.di.Inject;

@DefaultBean
@Getter
@Setter
public class ComplexOven {

HeatCoil coil;

@Inject
public ComplexOven(HeatCoil coil) {
this.coil = coil;
}
}
Loading
Loading