Created
July 15, 2015 18:51
-
-
Save jnericks/4a1bb585daea26fd6b23 to your computer and use it in GitHub Desktop.
SystemUnderTestFactoryNew.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.jnericks.testutils; | |
import java.lang.reflect.*; | |
import java.util.*; | |
import java.util.function.*; | |
import java.util.function.Supplier; | |
import static org.mockito.Mockito.*; | |
@SuppressWarnings("unchecked") | |
public class SystemUnderTestFactory<TSut> | |
{ | |
private final Class<TSut> _type; | |
private volatile Constructor<?> _ctor; | |
private ArrayList _dependencies; | |
private TSut _sut; | |
private Runnable _preProcessor; | |
private Supplier<TSut> _sutFactory; | |
private Consumer<TSut> _postProcessor; | |
public SystemUnderTestFactory(Class<TSut> type) | |
{ | |
_type = type; | |
_dependencies = new ArrayList(); | |
_ctor = getGreediestCtor(); | |
Class[] parameterTypes = _ctor.getParameterTypes(); | |
for (Class cls : parameterTypes) | |
{ | |
_dependencies.add(mock(cls)); | |
} | |
} | |
public void createSutUsing(Supplier<TSut> sutFactory) | |
{ | |
_sutFactory = sutFactory; | |
} | |
public void beforeSutCreated(Runnable preProcessor) | |
{ | |
_preProcessor = preProcessor; | |
} | |
public void afterSutCreated(Consumer<TSut> postProcessor) | |
{ | |
_postProcessor = postProcessor; | |
} | |
public void createSut() | |
{ | |
try | |
{ | |
if (_sut == null) | |
{ | |
if (_preProcessor != null) | |
_preProcessor.run(); | |
if (_sutFactory == null) | |
_sut = (TSut) _ctor.newInstance(_dependencies.toArray()); | |
else | |
_sut = _sutFactory.get(); | |
if (_postProcessor != null) | |
_postProcessor.accept(_sut); | |
} | |
} catch (IllegalAccessException | InvocationTargetException | InstantiationException ignored) { } | |
} | |
public TSut sut() | |
{ | |
createSut(); | |
return _sut; | |
} | |
public <TDependency> TDependency dependency(Class<TDependency> type) | |
{ | |
for (Object o : _dependencies) | |
{ | |
if (type.isAssignableFrom(o.getClass())) | |
{ | |
return (TDependency) o; | |
} | |
} | |
throw new UnsupportedOperationException(String | |
.format("%s is not a dependency of %s", type.getSimpleName(), _type.getSimpleName())); | |
} | |
public <TDependency> DoForDependency<TDependency> forDependency(Class<TDependency> type) | |
{ | |
for (int i = 0; i < _dependencies.size(); i++) | |
{ | |
if (type.isAssignableFrom(_dependencies.get(i).getClass())) | |
{ | |
return new DoForDependency(type, _dependencies, i); | |
} | |
} | |
throw new UnsupportedOperationException(String | |
.format("%s is not a dependency of %s", type.getSimpleName(), _type.getSimpleName())); | |
} | |
Constructor getGreediestCtor() | |
{ | |
Constructor[] ctors = _type.getConstructors(); | |
Constructor greediest = ctors[0]; | |
int count = greediest.getParameterCount(); | |
int len = ctors.length; | |
if (len > 1) | |
{ | |
for (int i = 1; i < len; i++) | |
{ | |
Constructor ctor = ctors[i]; | |
if (ctor.getParameterCount() > count) | |
{ | |
greediest = ctor; | |
count = ctor.getParameterCount(); | |
} | |
} | |
} | |
return greediest; | |
} | |
public class DoForDependency<TDoFor> | |
{ | |
final Class<TDoFor> _type; | |
ArrayList _dependencies; | |
int _index; | |
protected DoForDependency(Class<TDoFor> type, ArrayList dependencies, int index) | |
{ | |
_type = type; | |
_dependencies = dependencies; | |
_index = index; | |
} | |
public void use(TDoFor dependency) | |
{ | |
_dependencies.set(_index, dependency); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment