Skip to content

Instantly share code, notes, and snippets.

@abombss
Created February 5, 2011 07:39
Show Gist options
  • Save abombss/812297 to your computer and use it in GitHub Desktop.
Save abombss/812297 to your computer and use it in GitHub Desktop.
Poor Man's Mspec in Java
public class ContextRunner extends Runner {
static class SpecificationMethod {
Class<?> TestContainerType;
Description TestContainerDescription;
ContextSpecification ContextSpecification;
Description ContextSpecificationDescription;
Field ContextSpecificationField;
Method SpecificationMethod;
Description SpecificationDescription;
}
Description description;
private final Class<?> classToRun;
private final List<SpecificationMethod> specsToRun;
public ContextRunner(Class<?> classToRun) throws InitializationError {
this.classToRun = classToRun;
specsToRun = new LinkedList<SpecificationMethod>();
}
@Override
public Description getDescription() {
Description description = Description.createSuiteDescription(classToRun);
for(Field f : classToRun.getDeclaredFields()) {
if (Modifier.isStatic(f.getModifiers()) && ContextSpecification.class.isAssignableFrom(f.getType())) {
try {
f.setAccessible(true);
ContextSpecification contextSpecification = (ContextSpecification) f.get(null);
Description contextSpecificationDescription = Description.createSuiteDescription(f.getName());
Method[] methods = contextSpecification.getClass().getDeclaredMethods();
for(Method m : methods) {
if (m.getName().startsWith("it")) {
m.setAccessible(true);
SpecificationMethod specificationMethod = new SpecificationMethod();
specificationMethod.ContextSpecification = contextSpecification;
specificationMethod.TestContainerType = classToRun;
specificationMethod.TestContainerDescription = description;
specificationMethod.ContextSpecificationField = f;
specificationMethod.ContextSpecificationDescription = contextSpecificationDescription;
specificationMethod.SpecificationDescription = Description.createSuiteDescription(m.getName());
specificationMethod.SpecificationMethod = m;
specificationMethod.ContextSpecificationDescription.addChild(specificationMethod.SpecificationDescription);
specsToRun.add(specificationMethod);
}
}
description.addChild(contextSpecificationDescription);
} catch (IllegalAccessException ignore) {
}
}
}
return description;
}
@Override
public void run(RunNotifier runNotifier) {
ContextSpecification currentContext = null;
runNotifier.fireTestRunStarted(description);
for (SpecificationMethod m : specsToRun) {
if (currentContext != m.ContextSpecification) {
if (currentContext != null) {
currentContext.dispose();
runNotifier.fireTestRunFinished(new Result());
}
currentContext = m.ContextSpecification;
runNotifier.fireTestRunStarted(m.ContextSpecificationDescription);
currentContext.establish();
currentContext.becauseOf();
}
runNotifier.fireTestStarted(m.SpecificationDescription);
try {
m.SpecificationMethod.setAccessible(true);
m.SpecificationMethod.invoke(currentContext);
runNotifier.fireTestFinished(m.SpecificationDescription);
} catch (Exception e) {
runNotifier.fireTestFailure(new Failure(m.SpecificationDescription, e.getCause()));
}
}
if (currentContext != null) {
runNotifier.fireTestRunFinished(new Result());
}
runNotifier.fireTestRunFinished(new Result());
}
}
public abstract class ContextSpecification {
public void establish(){}
public void becauseOf(){}
public void dispose(){}
}
@RunWith(ContextRunner.class)
public class AtomicSpecs {
static ContextSpecification when_getting_the_injector_for_the_first_time = new ContextSpecification() {
Application application;
Injector injector;
public void establish() { application = mock(Application.class); }
public void becauseOf() { injector = Atomic.getInjector(application); }
public void it_should_create_an_injector() {
assertThat(injector, is(notNullValue()));
}
public void it_should_fail() {
assertThat(injector, is(nullValue()));
}
};
static ContextSpecification when_getting_the_injector_for_the_second_time = new ContextSpecification() {
Application application;
Injector injector;
Injector secondInjector;
public void establish() {
application = mock(Application.class);
injector = Atomic.getInjector(application);
}
public void becauseOf() {
secondInjector = Atomic.getInjector(application);
}
public void it_should_use_the_same_injector_as_the_first_time() {
assertThat(secondInjector, is(equalTo(injector)));
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment