001package io.avaje.inject.test; 002 003import io.avaje.inject.BeanScope; 004import io.avaje.inject.BeanScopeBuilder; 005import org.junit.jupiter.api.extension.AfterEachCallback; 006import org.junit.jupiter.api.extension.BeforeEachCallback; 007import org.junit.jupiter.api.extension.ExtensionContext; 008import org.junit.jupiter.api.extension.ExtensionContext.Namespace; 009 010import java.util.ArrayList; 011import java.util.List; 012 013/** 014 * Junit 5 extension for avaje inject. 015 * <p> 016 * Supports injection for fields annotated with <code>@Mock, @Spy, @Captor, @Inject</code>. 017 */ 018public class InjectExtension implements BeforeEachCallback, AfterEachCallback { 019 020 private final static Namespace INJECT_NS = Namespace.create("io.avaje.inject"); 021 022 private final static String BEAN_SCOPE = "BEAN_SCOPE"; 023 024 /** 025 * Callback that is invoked <em>before</em> each test is invoked. 026 */ 027 @Override 028 public void beforeEach(final ExtensionContext context) { 029 final List<MetaReader> readers = createMetaReaders(context); 030 031 final BeanScopeBuilder builder = BeanScope.newBuilder(); 032 for (MetaReader reader : readers) { 033 reader.build(builder); 034 } 035 036 final BeanScope beanScope = builder.build(); 037 for (MetaReader reader : readers) { 038 reader.setFromScope(beanScope); 039 } 040 context.getStore(INJECT_NS).put(BEAN_SCOPE, beanScope); 041 } 042 043 /** 044 * Return the list of MetaReaders - 1 per test instance. 045 */ 046 private List<MetaReader> createMetaReaders(ExtensionContext context) { 047 final List<Object> testInstances = context.getRequiredTestInstances().getAllInstances(); 048 final List<MetaReader> readers = new ArrayList<>(testInstances.size()); 049 for (Object testInstance : testInstances) { 050 readers.add(new MetaReader(testInstance)); 051 } 052 return readers; 053 } 054 055 /** 056 * Callback that is invoked <em>after</em> each test has been invoked. 057 */ 058 @Override 059 public void afterEach(ExtensionContext context) { 060 final BeanScope beanScope = (BeanScope) context.getStore(INJECT_NS).remove(BEAN_SCOPE); 061 if (beanScope != null) { 062 beanScope.close(); 063 } 064 } 065 066}