Skip to content

@EmptySource not working with ArgumentConverter accepting its supported types #4801

@scordio

Description

@scordio

Currently, EmptyArgumentsProvider directly checks the type of the first declared parameter and does not know of a potential converter declared for that parameter with its supported type(s), so it will throw a PreconditionViolationException if the declared type doesn't match the expectations.

Looking ahead to when #4219 is integrated, a globally-configured converter might even make the situation more complicated.

Steps to reproduce

Given an ArgumentConverter converting objects to their respective hash codes, like:

class ObjectToHashCodeConverter implements ArgumentConverter {

    @Override
    public Object convert(Object source, ParameterContext context) {
        return source.hashCode();
    }

}

the following test passes:

@ParameterizedTest
@FieldSource
void fieldSourceTest(@ConvertWith(ObjectToHashCodeConverter.class) int hashCode) {
    assertEquals(0, hashCode);
}

static List<?> fieldSourceTest = List.of("");

but the following test does not:

@ParameterizedTest
@EmptySource // no indication on which supported type to use
void emptySourceTest(@ConvertWith(ObjectToHashCodeConverter.class) int hashCode) {
    assertEquals(0, hashCode);
}

failing with:

org.junit.platform.commons.PreconditionViolationException: @EmptySource cannot provide an empty argument to method [void io.github.scordio.junit.converters.tests.MyTest.emptySourceTest(int)]: [int] is not a supported type.

	at [email protected]/org.junit.jupiter.params.provider.EmptyArgumentsProvider.provideArguments(EmptyArgumentsProvider.java:92)
	at [email protected]/org.junit.jupiter.params.ParameterizedInvocationContextProvider.arguments(ParameterizedInvocationContextProvider.java:79)
	at [email protected]/org.junit.jupiter.params.ParameterizedInvocationContextProvider.lambda$provideInvocationContexts$2(ParameterizedInvocationContextProvider.java:46)
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at [email protected]/org.junit.jupiter.engine.descriptor.TemplateExecutor.executeForProvider(TemplateExecutor.java:59)
	...

Similar reproducers can be composed for all other @EmptySource supported types, like Collection, Map, etc.

Context

  • Used versions (Jupiter/Vintage/Platform): 5.13.4
  • Build Tool/IDE: Maven/IntelliJ IDEA

Deliverables

  • @EmptySource provides an optional type attribute to select the desired type explicitly

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions