下面列出了怎么用 com.sun.codemodel.JCodeModel 的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void compilesOWS_V_1_1_0() throws Exception {
new File("target/generated-sources/ows-v_1_1_0").mkdirs();
URL schema = getClass().getResource("/ogc/ows/1.1.0/owsAll.xsd");
URL binding = getClass().getResource("/ogc/ows-v_1_1_0.xjb");
final String[] arguments = new String[] { "-xmlschema",
schema.toExternalForm(), "-b", binding.toExternalForm(), "-d",
"target/generated-sources/ows-v_1_1_0", "-extension",
"-Xjsonix"
};
Options options = new Options();
options.parseArguments(arguments);
ConsoleErrorReporter receiver = new ConsoleErrorReporter();
Model model = ModelLoader.load(options, new JCodeModel(), receiver);
model.generateCode(options, receiver);
com.sun.codemodel.CodeWriter cw = options.createCodeWriter();
model.codeModel.build(cw);
}
protected JavaCodeBuilder(JCodeModel codeModel, GenerationConfig generationConfig) {
this.codeModel = codeModel;
this.generationConfig = generationConfig;
Set<Property> occurredProperties = new HashSet<>();
this.globalProperties = filterProperties(occurredProperties,
CommonUtils.getSortedPropertiesBasedOnTabs(generationConfig.getOptions().getGlobalProperties(), generationConfig.getOptions().getGlobalTabProperties()));
occurredProperties.addAll(this.globalProperties);
this.sharedProperties = filterProperties(occurredProperties,
CommonUtils.getSortedPropertiesBasedOnTabs(generationConfig.getOptions().getSharedProperties(), generationConfig.getOptions().getSharedTabProperties()));
occurredProperties.addAll(this.sharedProperties);
this.privateProperties = filterProperties(occurredProperties,
CommonUtils.getSortedPropertiesBasedOnTabs(generationConfig.getOptions().getProperties(), generationConfig.getOptions().getTabProperties()));
occurredProperties.addAll(this.privateProperties);
}
void processToStruct(JFieldVar schemaField, JCodeModel codeModel, ClassOutline classOutline) {
final Map<String, JFieldVar> fields = classOutline.implClass.fields();
final JClass structClass = codeModel.ref(Struct.class);
final JMethod method = classOutline.implClass.method(JMod.PUBLIC, structClass, "toStruct");
final JBlock methodBody = method.body();
final JVar structVar = methodBody.decl(structClass, "struct", JExpr._new(structClass).arg(schemaField));
for (final Map.Entry<String, JFieldVar> field : fields.entrySet()) {
log.trace("processSchema() - processing name = '{}' type = '{}'", field.getKey(), field.getValue().type().name());
if (schemaField.name().equals(field.getKey())) {
log.trace("processSchema() - skipping '{}' cause we added it.", field.getKey());
continue;
}
methodBody.invoke(structVar, "put")
.arg(field.getKey())
.arg(JExpr.ref(JExpr._this(), field.getKey()));
}
methodBody._return(structVar);
}
@Test
public void compilesSchema() throws Exception {
new File("target/generated-sources/xjc").mkdirs();
URL schema = getClass().getResource("/schema.xsd");
URL binding = getClass().getResource("/bindings.xjb");
final String[] arguments = new String[] { "-xmlschema",
schema.toExternalForm(), "-b", binding.toExternalForm(), "-d",
"target/generated-sources/xjc", "-extension", "-Xsimplify", "-Xsimplify-usePluralForm=true"};
Options options = new Options();
options.parseArguments(arguments);
ConsoleErrorReporter receiver = new ConsoleErrorReporter();
Model model = ModelLoader.load(options, new JCodeModel(), receiver);
model.generateCode(options, receiver);
com.sun.codemodel.CodeWriter cw = options.createCodeWriter();
model.codeModel.build(cw);
}
protected JMethod generateCopyTo$copyTo(final ClassOutline classOutline,
final JDefinedClass theClass) {
final JCodeModel codeModel = theClass.owner();
final JMethod copyTo$copyTo = theClass.method(JMod.PUBLIC,
codeModel.ref(Object.class), "copyTo");
copyTo$copyTo.annotate(Override.class);
{
final JVar target = copyTo$copyTo.param(Object.class, "target");
final JBlock body = copyTo$copyTo.body();
final JVar copyStrategy = body.decl(JMod.FINAL,
codeModel.ref(CopyStrategy2.class), "strategy",
createCopyStrategy(codeModel));
body._return(JExpr.invoke("copyTo").arg(JExpr._null()).arg(target)
.arg(copyStrategy));
}
return copyTo$copyTo;
}
/**
* @throws IllegalStateException
* if a packageRule or classRule is missing or if the
* ApiControllerMetadata requires a missing methodSignatureRule.
*/
@Override
public JDefinedClass apply(ApiResourceMetadata metadata, JCodeModel codeModel) {
if (packageRule == null || classRule == null) {
throw new IllegalStateException("A packageRule and classRule are mandatory.");
}
if (!metadata.getApiCalls().isEmpty() && methodSignatureRule == null) {
throw new IllegalStateException("Since there are API Calls in the metadata at least a methodSignatureRule is mandatory");
}
JPackage jPackage = packageRule.apply(metadata, codeModel);
JDefinedClass jClass = classRule.apply(metadata, jPackage);
implementsExtendsRule.ifPresent(rule -> rule.apply(metadata, jClass));
classCommentRule.ifPresent(rule -> rule.apply(metadata, jClass));
classAnnotationRules.forEach(rule -> rule.apply(metadata, jClass));
fieldDeclerationRules.forEach(rule -> rule.apply(metadata, jClass));
metadata.getApiCalls().forEach(apiMappingMetadata -> {
JMethod jMethod = methodSignatureRule.apply(apiMappingMetadata, jClass);
methodCommentRule.ifPresent(rule -> rule.apply(apiMappingMetadata, jMethod));
methodAnnotationRules.forEach(rule -> rule.apply(apiMappingMetadata, jMethod));
methodBodyRule.ifPresent(rule -> rule.apply(apiMappingMetadata, CodeModelHelper.ext(jMethod, jClass.owner())));
});
return jClass;
}
public MModelInfo<NType, NClass> loadModel(String resource)
throws Exception {
System.setProperty("javax.xml.accessExternalSchema", "all");
new File("target/generated-sources/" + resource).mkdirs();
final String[] arguments = new String[] { "-xmlschema",
getClass().getResource("/" + resource).toExternalForm(), "-d",
"target/generated-sources/" + resource, "-extension",
"-Xjsonix", "-Xjsonix-generateJsonSchema" };
Options options = new Options();
options.parseArguments(arguments);
ConsoleErrorReporter receiver = new ConsoleErrorReporter();
Model model = ModelLoader.load(options, new JCodeModel(), receiver);
model.generateCode(options, receiver);
com.sun.codemodel.CodeWriter cw = options.createCodeWriter();
model.codeModel.build(cw);
final MModelInfo<NType, NClass> modelInfo = new XJCCMInfoFactory(model)
.createModel();
return modelInfo;
}
protected JMethod generateObject$toString(final ClassOutline classOutline,
final JDefinedClass theClass) {
final JCodeModel codeModel = theClass.owner();
final JMethod object$toString = theClass.method(JMod.PUBLIC,
codeModel.ref(String.class), "toString");
object$toString.annotate(Override.class);
{
final JBlock body = object$toString.body();
final JVar toStringStrategy =
body.decl(JMod.FINAL, codeModel.ref(ToStringStrategy2.class),
"strategy", createToStringStrategy(codeModel));
final JVar buffer = body.decl(JMod.FINAL,
codeModel.ref(StringBuilder.class), "buffer",
JExpr._new(codeModel.ref(StringBuilder.class)));
body.invoke("append").arg(JExpr._null()).arg(buffer)
.arg(toStringStrategy);
body._return(buffer.invoke("toString"));
}
return object$toString;
}
private void createReportingValueClass(JCodeModel codeModel, Class<? extends Value<?>> valueClazz, JPrimitiveType type) throws JClassAlreadyExistsException {
JClass reportClazz = codeModel.ref(Report.class);
JDefinedClass reportingValueClazz = codeModel._class(JMod.PUBLIC, asReportingClass(valueClazz), ClassType.CLASS);
reportingValueClazz._extends(codeModel.ref(valueClazz));
reportingValueClazz._implements(codeModel.ref(HasReport.class));
JFieldVar reportField = reportingValueClazz.field(JMod.PRIVATE, reportClazz, "report", JExpr._null());
createCopyMethod(reportingValueClazz);
createOperationMethods(reportingValueClazz, valueClazz, type);
createReportMethod(reportingValueClazz);
createExpressionMethods(reportingValueClazz);
createAccessorMethods(reportingValueClazz, reportField);
createFormatMethod(reportingValueClazz, type);
}
@Test
public void compilesContext_V_1_1_0() throws Exception {
new File("target/generated-sources/context-v_1_1_0").mkdirs();
final String[] arguments = new String[] {
"-xmlschema",
getClass().getResource("/ogc/context/1.1.0/wmcAll.xsd")
.toExternalForm(),
"-b",
getClass().getResource("/ogc/context-v_1_1_0.xjb")
.toExternalForm(), "-d",
"target/generated-sources/context-v_1_1_0", "-extension",
"-Xjsonix"
};
Options options = new Options();
options.parseArguments(arguments);
ConsoleErrorReporter receiver = new ConsoleErrorReporter();
Model model = ModelLoader.load(options, new JCodeModel(), receiver);
model.generateCode(options, receiver);
com.sun.codemodel.CodeWriter cw = options.createCodeWriter();
model.codeModel.build(cw);
}
@Test
public void compilesSchema() throws Exception {
new File("target/generated-sources/xjc").mkdirs();
URL schema = getClass().getResource("/cases.xsd");
// URL binding = getClass().getResource("/cases.xjb");
final String[] arguments = new String[] { "-xmlschema",
schema.toExternalForm(),
// "-b", binding.toExternalForm(),
"-d", "target/generated-sources/xjc", "-extension",
"-XsimpleHashCode", "-XsimpleEquals",
// "-XsimpleToString"
};
Options options = new Options();
options.parseArguments(arguments);
ConsoleErrorReporter receiver = new ConsoleErrorReporter();
Model model = ModelLoader.load(options, new JCodeModel(), receiver);
model.generateCode(options, receiver);
com.sun.codemodel.CodeWriter cw = options.createCodeWriter();
model.codeModel.build(cw);
}
@Inject
public NullCheckFactory(JCodeModel codeModel, ClassGenerationUtil generationUtil, UniqueVariableNamer namer, ASTClassFactory astClassFactory) {
this.codeModel = codeModel;
this.generationUtil = generationUtil;
this.namer = namer;
this.astClassFactory = astClassFactory;
}
protected void writeCode(Outline outline) throws MojoExecutionException {
if (getWriteCode()) {
final Model model = outline.getModel();
final JCodeModel codeModel = model.codeModel;
final File targetDirectory = model.options.targetDir;
if (getVerbose()) {
getLog().info(
MessageFormat.format("Writing output to [{0}].",
targetDirectory.getAbsolutePath()));
}
try {
if (getCleanPackageDirectories()) {
if (getVerbose()) {
getLog().info("Cleaning package directories.");
}
cleanPackageDirectories(targetDirectory, codeModel);
}
final CodeWriter codeWriter = new LoggingCodeWriter(
model.options.createCodeWriter(), getLog(),
getVerbose());
codeModel.build(codeWriter);
} catch (IOException e) {
throw new MojoExecutionException("Unable to write files: "
+ e.getMessage(), e);
}
} else {
getLog().info(
"The [writeCode] setting is set to false, the code will not be written.");
}
}
public SchemaAssistant(JCodeModel codeModel, boolean useGenericTypes, Class defaultStringClass) {
this.codeModel = codeModel;
this.useGenericTypes = useGenericTypes;
/**
* Use {@link TreeSet} here to make sure the code gen is deterministic.
*/
this.exceptionsFromStringable = new TreeSet<>(Comparator.comparing(Class::getCanonicalName));
this.defaultStringType = codeModel.ref(defaultStringClass);
}
@Override
public boolean run(Outline model, Options options, ErrorHandler errorHandler) throws SAXException {
JCodeModel codeModel = model.getCodeModel();
for (ClassOutline classOutline : model.getClasses()) {
log.trace("run - {}", classOutline.implClass.name());
JFieldVar schemaField = processSchema(codeModel, classOutline);
processToStruct(schemaField, codeModel, classOutline);
processFromStruct(codeModel, classOutline);
}
return true;
}
FastDeserializerGeneratorBase(Schema writer, Schema reader, File destination, ClassLoader classLoader,
String compileClassPath) {
this.writer = writer;
this.reader = reader;
this.destination = destination;
this.classLoader = classLoader;
this.compileClassPath = compileClassPath;
codeModel = new JCodeModel();
}
FastSerializerGeneratorBase(Schema schema, File destination, ClassLoader classLoader,
String compileClassPath) {
this.schema = schema;
this.destination = destination;
this.classLoader = classLoader;
this.compileClassPath = compileClassPath;
codeModel = new JCodeModel();
}
private void collectQueryParams(JCodeModel codeModel, Entry<String, RamlQueryParameter> queryParameter) {
if (queryParameter.getValue() instanceof RJP10V2RamlQueryParameter) {
RamlDataType type = ((RJP10V2RamlQueryParameter) queryParameter.getValue()).getRamlDataType();
if (type != null) {
RamlTypeHelper.mapTypeToPojo(codeModel, parent.getDocument(), type.getType());
}
}
requestParameters.add(new ApiParameterMetadata(queryParameter.getKey(), queryParameter.getValue(), codeModel));
}
public ApiBodyMetadata(String name, TypeDeclaration type, boolean array, JCodeModel codeModel) {
super();
this.schema = null;
this.type = type;
this.name = name;
this.codeModel = codeModel;
this.array = array;
// array detection. i think we can default this to false since we should
// already be generating lists from the type. nope we need it within
// rules for narrowing to List
}
@SuppressWarnings("unchecked")
ClassGenerator(CodeGenerator<T> codeGenerator, MappingSet mappingSet, SignatureHolder signature, EvaluationVisitor eval, JDefinedClass clazz, JCodeModel model) throws JClassAlreadyExistsException {
this.codeGenerator = codeGenerator;
this.clazz = clazz;
this.mappings = mappingSet;
this.sig = signature;
this.evaluationVisitor = eval;
this.model = Preconditions.checkNotNull(model, "Code model object cannot be null.");
blocks = new LinkedList[sig.size()];
for (int i =0; i < sig.size(); i++) {
blocks[i] = Lists.newLinkedList();
}
rotateBlock();
for (SignatureHolder child : signature.getChildHolders()) {
final String innerClassName = child.getSignatureClass().getSimpleName();
final JDefinedClass innerClazz;
// we need to extend the template class and avoid using static inner classes.
innerClazz = clazz._class(JMod.FINAL, innerClassName)._extends(child.getSignatureClass());
// we also need to delegate any inner class constructors.
for(Constructor<?> c : child.getSignatureClass().getDeclaredConstructors()){
final Class<?>[] params = c.getParameterTypes();
JMethod constructor = innerClazz.constructor(JMod.PUBLIC);
JBlock block = constructor.body();
JInvocation invoke = block.invoke("super");
block.invoke(SignatureHolder.INIT_METHOD);
// start at 1 since first parameter is the parent class
for (int i = 1; i < params.length; i++) {
constructor.param(params[i], "arg" + i);
invoke.arg(JExpr.direct("arg" + i));
}
}
innerClasses.put(innerClassName, new ClassGenerator<>(codeGenerator, mappingSet, child, eval, innerClazz, model));
}
}
static
private JType toType(JCodeModel codeModel, TypeMirror typeMirror){
String name = typeMirror.toString();
if(name.endsWith("Value<?>")){
name = name.substring(0, name.length() - "Value<?>".length()) + "Value<? extends java.lang.Number>";
}
try {
return codeModel.parseType(name);
} catch(ClassNotFoundException cnfe){
throw new RuntimeException(cnfe);
}
}
public static JExpression unmarshallJAXBElement(JCodeModel codeModel,
JExpression value) {
final JExpression argument = value;
return codeModel.ref(XmlAdapterUtils.class).staticInvoke(
"unmarshallJAXBElement").arg(argument);
}
public void testParse() throws Exception {
final JavaTypeParser javaTypeParser = new JavaTypeParser();
final JCodeModel codeModel = new JCodeModel();
JClass comparator = javaTypeParser.parseClass("java.util.Comparator",
codeModel);
assertNotNull(comparator);
JClass integerComparator = javaTypeParser.parseClass(
"java.util.Comparator<java.lang.Integer>", codeModel);
assertNotNull(integerComparator);
JClass wildcardIntegerComparator = javaTypeParser.parseClass(
"java.util.Comparator<? extends java.lang.Integer>", codeModel);
assertNotNull(wildcardIntegerComparator);
}
private JClass resolveCollectionClass(ArrayTypeDeclaration arrayType, JClass resolvedClass, JCodeModel builderModel) {
Class<?> container = List.class;
if (arrayType.uniqueItems() != null && arrayType.uniqueItems()) {
container = Set.class;
}
return builderModel.ref(container).narrow(resolvedClass);
}
protected Model loadModel(Options options) throws MojoExecutionException {
if (getVerbose()) {
getLog().info("Parsing input schema(s)...");
}
final Model model = ModelLoader.load(options, new JCodeModel(),
new LoggingErrorReceiver("Error while parsing schema(s).",
getLog(), getVerbose()));
if (model == null)
throw new MojoExecutionException(
"Unable to parse input schema(s). Error messages should have been provided.");
return model;
}
@BeforeClass
public static void createModel() throws BadCommandLineException,
IOException {
final String generateDirectory = "target/generated-sources/"
+ AlphaMInfoFactoryTest.class.getPackage().getName();
new File(generateDirectory).mkdirs();
final URL schema = AlphaMInfoFactoryTest.class
.getResource("schema.xsd");
final URL binding = AlphaMInfoFactoryTest.class
.getResource("binding.xjb");
final String[] arguments = new String[] { "-xmlschema",
schema.toExternalForm(), "-b", binding.toExternalForm(), "-d",
generateDirectory, "-extension" };
Options options = new Options();
options.parseArguments(arguments);
ConsoleErrorReporter receiver = new ConsoleErrorReporter();
Model model = ModelLoader.load(options, new JCodeModel(), receiver);
Assert.assertNotNull(model);
final XJCCMInfoFactory factory = new XJCCMInfoFactory(model);
AlphaMInfoFactoryTest.MODEL_INFO = factory.createModel();
model.generateCode(options, receiver);
com.sun.codemodel.CodeWriter cw = options.createCodeWriter();
model.codeModel.build(cw);
}
@Test
public void testClassWithPersistenceContextWithKonfiguredUnitNameSpecified() throws Exception {
// GIVEN
final JCodeModel jCodeModel = new JCodeModel();
final JPackage jp = jCodeModel.rootPackage();
final JDefinedClass jClass = jp._class(JMod.PUBLIC, "ClassUnderTest");
final JFieldVar ruleField = jClass.field(JMod.PUBLIC, JpaUnitRule.class, "rule");
ruleField.annotate(Rule.class);
final JInvocation instance = JExpr._new(jCodeModel.ref(JpaUnitRule.class)).arg(JExpr.direct("getClass()"));
ruleField.init(instance);
final JFieldVar emField = jClass.field(JMod.PRIVATE, EntityManager.class, "em");
final JAnnotationUse jAnnotation = emField.annotate(PersistenceContext.class);
jAnnotation.param("unitName", "test-unit-1");
final JMethod jMethod = jClass.method(JMod.PUBLIC, jCodeModel.VOID, "testMethod");
jMethod.annotate(Test.class);
buildModel(testFolder.getRoot(), jCodeModel);
compileModel(testFolder.getRoot());
final Class<?> cut = loadClass(testFolder.getRoot(), jClass.name());
final BlockJUnit4ClassRunner runner = new BlockJUnit4ClassRunner(cut);
final RunListener listener = mock(RunListener.class);
final RunNotifier notifier = new RunNotifier();
notifier.addListener(listener);
// WHEN
runner.run(notifier);
// THEN
final ArgumentCaptor<Description> descriptionCaptor = ArgumentCaptor.forClass(Description.class);
verify(listener).testStarted(descriptionCaptor.capture());
assertThat(descriptionCaptor.getValue().getClassName(), equalTo("ClassUnderTest"));
assertThat(descriptionCaptor.getValue().getMethodName(), equalTo("testMethod"));
verify(listener).testFinished(descriptionCaptor.capture());
assertThat(descriptionCaptor.getValue().getClassName(), equalTo("ClassUnderTest"));
assertThat(descriptionCaptor.getValue().getMethodName(), equalTo("testMethod"));
}
@Test
public void testClassWithPersistenceUnitWithKonfiguredUnitNameSpecified() throws Exception {
// GIVEN
final JCodeModel jCodeModel = new JCodeModel();
final JPackage jp = jCodeModel.rootPackage();
final JDefinedClass jClass = jp._class(JMod.PUBLIC, "ClassUnderTest");
final JFieldVar ruleField = jClass.field(JMod.PUBLIC, JpaUnitRule.class, "rule");
ruleField.annotate(Rule.class);
final JInvocation instance = JExpr._new(jCodeModel.ref(JpaUnitRule.class)).arg(JExpr.direct("getClass()"));
ruleField.init(instance);
final JFieldVar emField = jClass.field(JMod.PRIVATE, EntityManagerFactory.class, "emf");
final JAnnotationUse jAnnotation = emField.annotate(PersistenceUnit.class);
jAnnotation.param("unitName", "test-unit-1");
final JMethod jMethod = jClass.method(JMod.PUBLIC, jCodeModel.VOID, "testMethod");
jMethod.annotate(Test.class);
buildModel(testFolder.getRoot(), jCodeModel);
compileModel(testFolder.getRoot());
final Class<?> cut = loadClass(testFolder.getRoot(), jClass.name());
final BlockJUnit4ClassRunner runner = new BlockJUnit4ClassRunner(cut);
final RunListener listener = mock(RunListener.class);
final RunNotifier notifier = new RunNotifier();
notifier.addListener(listener);
// WHEN
runner.run(notifier);
// THEN
final ArgumentCaptor<Description> descriptionCaptor = ArgumentCaptor.forClass(Description.class);
verify(listener).testStarted(descriptionCaptor.capture());
assertThat(descriptionCaptor.getValue().getClassName(), equalTo("ClassUnderTest"));
assertThat(descriptionCaptor.getValue().getMethodName(), equalTo("testMethod"));
verify(listener).testFinished(descriptionCaptor.capture());
assertThat(descriptionCaptor.getValue().getClassName(), equalTo("ClassUnderTest"));
assertThat(descriptionCaptor.getValue().getMethodName(), equalTo("testMethod"));
}
protected void writeCode(Outline outline) throws MojoExecutionException {
if (getWriteCode()) {
final Model model = outline.getModel();
final JCodeModel codeModel = model.codeModel;
final File targetDirectory = model.options.targetDir;
if (getVerbose()) {
getLog().info(
MessageFormat.format("Writing output to [{0}].",
targetDirectory.getAbsolutePath()));
}
try {
if (getCleanPackageDirectories()) {
if (getVerbose()) {
getLog().info("Cleaning package directories.");
}
cleanPackageDirectories(targetDirectory, codeModel);
}
final CodeWriter codeWriter = new LoggingCodeWriter(
model.options.createCodeWriter(), getLog(),
getVerbose());
codeModel.build(codeWriter);
} catch (IOException e) {
throw new MojoExecutionException("Unable to write files: "
+ e.getMessage(), e);
}
} else {
getLog().info(
"The [writeCode] setting is set to false, the code will not be written.");
}
}
@Test
public void testClassWithMultiplePersistenceContextFields() throws Exception {
// GIVEN
final JCodeModel jCodeModel = new JCodeModel();
final JPackage jp = jCodeModel.rootPackage();
final JDefinedClass jClass = jp._class(JMod.PUBLIC, "ClassUnderTest");
final JAnnotationUse jAnnotationUse = jClass.annotate(RunWith.class);
jAnnotationUse.param("value", JpaUnitRunner.class);
final JFieldVar em1Field = jClass.field(JMod.PRIVATE, EntityManager.class, "em1");
em1Field.annotate(PersistenceContext.class);
final JFieldVar em2Field = jClass.field(JMod.PRIVATE, EntityManager.class, "em2");
em2Field.annotate(PersistenceContext.class);
final JMethod jMethod = jClass.method(JMod.PUBLIC, jCodeModel.VOID, "testMethod");
jMethod.annotate(Test.class);
buildModel(testFolder.getRoot(), jCodeModel);
compileModel(testFolder.getRoot());
final Class<?> cut = loadClass(testFolder.getRoot(), jClass.name());
final RunListener listener = mock(RunListener.class);
final RunNotifier notifier = new RunNotifier();
notifier.addListener(listener);
final JpaUnitRunner runner = new JpaUnitRunner(cut);
// WHEN
runner.run(notifier);
// THEN
final ArgumentCaptor<Failure> failureCaptor = ArgumentCaptor.forClass(Failure.class);
verify(listener).testFailure(failureCaptor.capture());
final Failure failure = failureCaptor.getValue();
assertThat(failure.getException().getClass(), equalTo(IllegalArgumentException.class));
assertThat(failure.getException().getMessage(), containsString("Only single field is allowed"));
}