Skip to content

#203 #204 - Add @InjectTest + TestScopeBean with helper methods to programmatically use the test scope #205

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

Merged
merged 5 commits into from
May 5, 2022
Merged
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
2 changes: 1 addition & 1 deletion blackbox-test-inject/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>avaje-inject-parent</artifactId>
<groupId>io.avaje</groupId>
<version>8.2</version>
<version>8.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class Main {

public static void main(String[] args) {

BeanScope beanScope = BeanScope.newBuilder().build();
BeanScope beanScope = BeanScope.builder().build();

HelloService helloService = beanScope.get(HelloService.class);
String greeting = helloService.hello();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ExampleServiceTest {

@Test
void exercise() {
try (BeanScope beanScope = BeanScope.newBuilder().build()) {
try (BeanScope beanScope = BeanScope.builder().build()) {
ExampleService exampleService = beanScope.get(ExampleService.class);

exampleService.other("foo", 42);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class HelloServiceTest {
@Test
void basic() throws IOException {
// just wire everything with no test scope, mocks etc
BeanScope beanScope = BeanScope.newBuilder().build();
BeanScope beanScope = BeanScope.builder().build();

HelloService helloService = beanScope.get(HelloService.class);
assertEquals("bazz foo 42", helloService.bazz("foo", 42));
Expand All @@ -30,7 +30,7 @@ void basic() throws IOException {
@Test
void skip() {
// just wire everything with no test scope, mocks etc
BeanScope beanScope = BeanScope.newBuilder().build();
BeanScope beanScope = BeanScope.builder().build();

HelloService helloService = beanScope.get(HelloService.class);
String result = helloService.skipExample("echo me back");
Expand All @@ -39,7 +39,7 @@ void skip() {

@Test
void aspect_multiInvoke() {
BeanScope beanScope = BeanScope.newBuilder().build();
BeanScope beanScope = BeanScope.builder().build();

MyMultiInvokeAspect aspect = beanScope.get(MyMultiInvokeAspect.class);
HelloService helloService = beanScope.get(HelloService.class);
Expand All @@ -51,7 +51,7 @@ void aspect_multiInvoke() {

@Test
void aspect_checkedRunnable() throws IOException, ClassNotFoundException {
BeanScope beanScope = BeanScope.newBuilder().build();
BeanScope beanScope = BeanScope.builder().build();

MyAroundAspect aspect = beanScope.get(MyAroundAspect.class);
HelloService helloService = beanScope.get(HelloService.class);
Expand All @@ -67,7 +67,7 @@ void aspect_checkedRunnable() throws IOException, ClassNotFoundException {

@Test
void aspect_throwingUndeclaredException_expect_InvocationException() {
BeanScope beanScope = BeanScope.newBuilder().build();
BeanScope beanScope = BeanScope.builder().build();

HelloService helloService = beanScope.get(HelloService.class);

Expand All @@ -80,7 +80,7 @@ void aspect_throwingUndeclaredException_expect_InvocationException() {

@Test
void aspect_appCodeThrowingUnchecked_expect_InvocationException() {
BeanScope beanScope = BeanScope.newBuilder().build();
BeanScope beanScope = BeanScope.builder().build();

HelloService helloService = beanScope.get(HelloService.class);

Expand All @@ -92,7 +92,7 @@ void aspect_appCodeThrowingUnchecked_expect_InvocationException() {

@Test
void aspect_appCodeThrowingDeclared_expect_declaredException() {
BeanScope beanScope = BeanScope.newBuilder().build();
BeanScope beanScope = BeanScope.builder().build();

HelloService helloService = beanScope.get(HelloService.class);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.example.myapp;

import io.avaje.inject.test.InjectTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;

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

@InjectTest
class InjectExtension_viaAnnotation_Test {

@Inject
HelloService helloService;

@Test
void hello_1() {
assertEquals("hello+TestHelloData", helloService.hello());
}

@Test
void hello_2() {
assertEquals("hello+TestHelloData", helloService.hello());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class OtherServiceProxyTest {
@Test
void proxyMethodInvocation() {

BeanScope beanScope = BeanScope.newBuilder().build();
BeanScope beanScope = BeanScope.builder().build();
OtherService otherService = beanScope.get(OtherService.class);

String result = otherService.other("foo", 42);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ void test_underlying_mechanics() {

// if (testMod.isPresent()) {
// // build what is our "global test BeanScope" which we use as a parent for all tests
// BeanScope parent = BeanScope.newBuilder()
// .withModules(testMod.get())
// BeanScope parent = BeanScope.builder()
// .modules(testMod.get())
// .build();
//
// // a test creates a BeanScope with the parent of our "global test BeanScope"
// BeanScope child = BeanScope.newBuilder().withParent(parent, false).build();
// BeanScope child = BeanScope.builder().parent(parent, false).build();
//
// HelloService helloService = child.get(HelloService.class);
// assertEquals("hello+TestHelloData", helloService.hello());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Resilience4J_retry_Test {
void retry_test() {

MyExample myExample;
try (BeanScope beanScope = BeanScope.newBuilder().build()) {
try (BeanScope beanScope = BeanScope.builder().build()) {
myExample = beanScope.get(MyExample.class);

assertThatThrownBy(myExample::doingItWithRetry)
Expand All @@ -31,7 +31,7 @@ void retry_test() {
void retry_fallback_test() {

MyExample myExample;
try (BeanScope beanScope = BeanScope.newBuilder().build()) {
try (BeanScope beanScope = BeanScope.builder().build()) {
myExample = beanScope.get(MyExample.class);

String result = myExample.retryWithFallback();
Expand All @@ -46,7 +46,7 @@ void retry_fallback_test() {
void retry_fallback_throwable_test() {

MyExample myExample;
try (BeanScope beanScope = BeanScope.newBuilder().build()) {
try (BeanScope beanScope = BeanScope.builder().build()) {
myExample = beanScope.get(MyExample.class);

String result = myExample.retry2("foo", 45);
Expand Down
4 changes: 2 additions & 2 deletions inject-generator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject-parent</artifactId>
<version>8.2</version>
<version>8.3</version>
</parent>

<artifactId>avaje-inject-generator</artifactId>
Expand All @@ -16,7 +16,7 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject</artifactId>
<version>8.2</version>
<version>8.3</version>
</dependency>

<!-- test dependencies -->
Expand Down
4 changes: 2 additions & 2 deletions inject-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject-parent</artifactId>
<version>8.2</version>
<version>8.3</version>
</parent>

<artifactId>avaje-inject-test</artifactId>
Expand Down Expand Up @@ -124,7 +124,7 @@
<path>
<groupId>io.avaje</groupId>
<artifactId>avaje-inject-generator</artifactId>
<version>8.2</version>
<version>8.3</version>
</path>
</annotationProcessorPaths>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,17 @@

import io.avaje.inject.BeanScope;
import io.avaje.inject.BeanScopeBuilder;
import io.avaje.inject.spi.Module;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;

import java.io.*;
import java.lang.System.Logger.Level;
import java.net.URL;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

import static java.util.Collections.singletonList;

/**
* Junit 5 extension for avaje inject.
* <p>
Expand Down Expand Up @@ -58,54 +54,11 @@ public void close() {
}

private void initialiseGlobalTestScope(ExtensionContext context) {
List<TestModule> testModules = new ArrayList<>();
for (TestModule next : ServiceLoader.load(TestModule.class)) {
testModules.add(next);
}
if (testModules.isEmpty()) {
registerViaResources(context);
} else {
registerTestModule(context, testModules);
}
}

private void registerTestModule(ExtensionContext context, List<TestModule> testModules) {
log.log(Level.DEBUG, "Building global test BeanScope (as parent scope for tests)");
globalTestScope = BeanScope.newBuilder()
.withModules(testModules.toArray(Module[]::new))
.build();

log.log(Level.TRACE, "register global test BeanScope with beans %s", globalTestScope);
context.getRoot().getStore(Namespace.GLOBAL).put(InjectExtension.class.getCanonicalName(), this);
}

/**
* Fallback when ServiceLoader does not work in module-path for generated test service.
*/
private void registerViaResources(ExtensionContext context) {
try {
URL url = ClassLoader.getSystemResource("META-INF/services/io.avaje.inject.test.TestModule");
String className = readServiceClassName(url);
if (className != null) {
Class<?> cls = Class.forName(className);
TestModule testModule = (TestModule) cls.getDeclaredConstructor().newInstance();
registerTestModule(context, singletonList(testModule));
}
} catch (Throwable e) {
throw new RuntimeException("Error trying to create TestModule", e);
}
}

private String readServiceClassName(URL url) throws IOException {
if (url != null) {
InputStream is = url.openStream();
if (is != null) {
try (LineNumberReader lineNumberReader = new LineNumberReader(new InputStreamReader(is))) {
return lineNumberReader.readLine();
}
}
globalTestScope = TestBeanScope.init(false);
if (globalTestScope != null) {
log.log(Level.TRACE, "register global test BeanScope with beans {0}", globalTestScope);
context.getRoot().getStore(Namespace.GLOBAL).put(InjectExtension.class.getCanonicalName(), this);
}
return null;
}

/**
Expand All @@ -114,10 +67,9 @@ private String readServiceClassName(URL url) throws IOException {
@Override
public void beforeEach(final ExtensionContext context) {
final List<MetaReader> readers = createMetaReaders(context);

final BeanScopeBuilder builder = BeanScope.newBuilder();
final BeanScopeBuilder builder = BeanScope.builder();
if (globalTestScope != null) {
builder.withParent(globalTestScope, false);
builder.parent(globalTestScope, false);
}
// register mocks and spies local to this test
for (MetaReader reader : readers) {
Expand All @@ -129,7 +81,7 @@ public void beforeEach(final ExtensionContext context) {
for (MetaReader reader : readers) {
reader.setFromScope(beanScope);
}
log.log(Level.TRACE, "test setup with %s", readers);
log.log(Level.TRACE, "test setup with {0}", readers);
context.getStore(INJECT_NS).put(BEAN_SCOPE, beanScope);
}

Expand Down
21 changes: 21 additions & 0 deletions inject-test/src/main/java/io/avaje/inject/test/InjectTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.avaje.inject.test;

import org.junit.jupiter.api.extension.ExtendWith;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* An avaje-inject test supporting {@code @Inject} along with Mockito
* annotations - {@code @Mock, @Spy, @Captor}.
* <p>
* This is a JUnit 5 extension.
*/
@ExtendWith(InjectExtension.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectTest {

}
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ private Object captorFor(Field field) {
void build(BeanScopeBuilder builder) {
final BeanScopeBuilder.ForTesting forTesting = builder.forTesting();
for (FieldTarget target : mocks) {
forTesting.withMock(target.type(), target.name());
forTesting.mock(target.type(), target.name());
}
for (FieldTarget target : spies) {
forTesting.withSpy(target.type(), target.name());
forTesting.spy(target.type(), target.name());
}
}

Expand Down
Loading